UIImageView,UIImage,CGContextRef

萧晔
2023-12-01

1.UIImageView不支持内部图片平铺(tile)

  UIImageView类充分去绘制它的图片,不去调用drawRect.要想自绘,必须继承UIView.
The UIImageView class is optimized to draw its images to the display. UIImageView will not call drawRect: a subclass. If your subclass needs custom drawing code, it is recommended you use UIView as the base class.

  //把图片作为view的背景,可以达到按view尺寸平铺图片的效果

  view.backgroundColor=[UIColor colorWithPatternImage:image] ;


2.资源中的图片要用小写的,模拟器中可能不区分大小写,但在真机中区分.

   [UIImage imageNamed:@""]; 在设备中区分大小写


3.UIView没有背景图属性,有背景色属性.设置背景图可以用addSubView(backgroundImage);,推荐的是设置背景色。


4.[UIImage imageNamed:@""];它是有缓存特性的

  This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.

  On a device running iOS 4 or later, the behavior is identical if the device’s screen has a scale of1.0. If the screen has a scale of2.0, this method first searches for an image file with the same filename with an@2x suffix appended to it. For example, if the file’s name isbutton, it first searches forbutton@2x. If it finds a 2x, it loads that image and sets thescale property of the returnedUIImage object to2.0. Otherwise, it loads the unmodified filename and sets thescale property to1.0.

   On iOS 4 and later, the name of the file is not required to specify the filename extension. Prior to iOS 4, you must specify the filename extension.

    可能在多次操作之后,应用经常发生内存警告从而导致自动退出的问题。定位之后发现是由于[UIImage imageNamed: @""]分配的图像都没有释放引起的。而之前从官方的reference中得到的信息应该是[UIImage imageNamed:@""]分配的图像系统会放到cache里面。而关于cache管理的规则就没有明确的介绍。由此看来[UIImage imageNamed:]只适合与UI界面中小的贴图的读取,而一些比较大的资源文件应该尽量避免使用这个接口。

    + (UIImage *)imageWithContentsOfFile:(NSString *)path  这个方法does not cache the image object.


 5. UIImage的 - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight

     指定两个方向上不被缩放的部分。

     对应的 rightCapWidth = image.size.width - (image.leftCapWidth + 1);

                bottomCapHeight = image.size.height - (image.topCapHeight + 1);

     leftCapWidth,rightCapWidth之间的,topCapHeight,bottomCapHeight之间的一像素被平铺以达到缩放效果。

     另外UIView.contentStretch在这里好像不起作用。

      注意:使用这个函数时,要取它的返回值。并且 That method could return nil if the base image is less than 5 pixels wide or 5 pixels tall since it needs the 4 pixels for the caps + 1 pixel to stretch.

示例:设置导航栏上的自定义返回按钮

- (void)setNavigationBackButton
{
    const int KLeftWidth=25;
    UIImage* image=[[UIImage imageNamed:@"back.png"] stretchableImageWithLeftCapWidth:KLeftWidth topCapHeight:0];
    UIImage* hightlightedImage=[[UIImage imageNamed:@"back_pressed.png"] stretchableImageWithLeftCapWidth:KLeftWidth topCapHeight:0];
    NSString* text=[[[self.navigationController viewControllers] objectAtIndex:0] navigationItem].title;
    UIFont* font=[Utility fontWithSize:12];
    CGSize stringSize = [text sizeWithFont:font];
    CGFloat textWidth = stringSize.width+KLeftWidth;
    
    UIButton* button=[UIViewUtil createUIButtonWithImage:image
                                       hightlightedImage:hightlightedImage  
                                           selectedImage:nil
                                                   title:text
                                              titleColor:color(0x33,0x33,0x33)
                                                    posX:0 posY:0];
    button.titleLabel.font=[Utility fontWithSize:12];
    CGRect rect=button.frame;
    rect.size.width=textWidth;
    button.frame=rect;
    UIBarButtonItem* buttonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    [button addTarget:self action:@selector(popViewControllerAnimated) forControlEvents:UIControlEventTouchUpInside];
    [[self navigationItem] setLeftBarButtonItem:buttonItem];
    [buttonItem release];
    [button release];    
}

6.支持内置动画,播放图片序列。

    imageView.animationImages = imageArray;
    imageView.animationDuration = 0.75f;
    [self.view addSubview:imageView];
    [imageView startAnimating];

7.UIImageView要设置self.userInteractionEnabled = YES才支持交互。

8. 构建图像的方式:

    UIGraphicsBeginImageContext(CGSizeMake(SIDE_LENGTH, SIDE_LENGTH));//创建一个新图像上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    ...
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();//将上下文转为一个UIImage对象。

    UIGraphicsEndImageContext();

    return theImage;


9.动态图像,如gif,貌似 iphone不支持动态图象,采用UIWebView替代显示gif。

   (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

{    

        NSString* referenceURL=[info objectForKey:UIImagePickerControllerReferenceURL];
        NSLog(@"%@",referenceURL);  //assets-library://asset/asset.JPG?id=1000000001&ext=JPG
        
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

...
}

#import <AssetsLibrary/ALAssetsLibrary.h>
#import <AssetsLibrary/ALAssetRepresentation.h>

http://stackoverflow.com/questions/5187251/ios-select-a-gif-from-the-photo-library-convert-to-nsdata-for-use-in-multipart

10.保存图片到相册

-(void)saveToPhotosAlbum
{
    UIImage* image=nil;
    NSObject* obj=..;
    if([obj isKindOfClass:[UIImage class]])
    {
        image=(UIImage*)obj;
    }
    else
    {
        image=[UIImage imageWithData:(NSData *)obj];
    }

    if(image)
    {
        UIImageWriteToSavedPhotosAlbum(image,self,@selector(image:didFinishSavingWithError:contextInfo:), nil); 
    }
    else
    {
         //@"保存失败";
    }
}

#if 1  
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo  
{  
    if (error == nil)  
        //@"保存成功";
    else  
       //@"保存失败";
}  
#endif 

11.emoji表情

emoji是日本开发的一字符编码集,在iOS中集成了该字符集, 可以通过编程的方式判断,开启或关闭该功能。


已测试它可显示于UILabel,UIButton,UIWebView,使用如“\ue415”的unicode码。

http://pukupi.com/post/1964/

http://www.easyapns.com/iphone-emoji-alerts

http://www.emoji-cheat-sheet.com/

http://en.wikipedia.org/wiki/Emoji



可结合NSString的draw方法,把表情画到UIImage上:

CGSize size = [text sizeWithFont:aFont];
    if (UIGraphicsBeginImageContextWithOptions != NULL)
    {
        UIGraphicsBeginImageContextWithOptions(size,NO,0.0);
    }
    else
    {
        UIGraphicsBeginImageContext(size);
    }
    [text drawAtPoint:CGPointMake(0.0, 0.0) withFont:aFont];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();    
    return image;

 
编程开启iOS emoji,未测试成功。
http://blog.csdn.net/favormm/article/details/6774899


iOS5.1下emoji表情显示方框的解决办法   

在iOS5.1的部分设备上,emoji表情无法正常显示.原因是iOS4上面的emoji用的是softbank的编码,到iOS5以后,emoji被放进了Unicode6.0,导致原来的老编码可能存在部分不兼容现象.
解决办法在iOS5上面全部用新编码,在iOS4及以下全部用老编码.
因为有些iOS5.1上可以正常显示,有些不行。根据我们的测试情况,5.x的全部用新编码,4.x及以下全部用老编码就没问题了
苹果自己的转换表: http://opensource.apple.com/source/ICU/ICU-461.13/icuSources/data/translit/Any_SoftbankSMS.txt 左边的是Unicode新编码,右边是softbank的老编码,请自行转换

http://www.cocoachina.com/bbs/read.php?tid=96847&page=1


12.UIImagePickerController 拍照后,图片旋转了90度。可能这个情况在5.0就不出现了。

#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [picker dismissModalViewControllerAnimated:YES];
    
    NSString* mediaType=[info objectForKey:UIImagePickerControllerMediaType];
    if([mediaType isEqualToString:(NSString*)kUTTypeImage])//@"public.image"
    {
        UIImage* image=[info objectForKey:UIImagePickerControllerOriginalImage];
        UIImageOrientation imageOrientation=image.imageOrientation;
        if(imageOrientation!=UIImageOrientationUp)
        {
            // 原始图片可以根据照相时的角度来显示,但UIImage无法判定,于是出现获取的图片会向左转90度的现象。
            // 以下为调整图片角度的部分
            UIGraphicsBeginImageContext(image.size);
            [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
            iPortraitImageView.image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            // 调整图片角度完毕
        }
    }
}  


//设置可编辑选取的图片

UIImagePickerController* pickerController = [[UIImagePickerController alloc] init];
        pickerController.delegate = self;
        pickerController.allowsEditing=YES;//设置可编辑选取的图片

        if(buttonIndex==0)
        {
            if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
            {
                pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            }
        }
        else
        {
            if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
            {
                pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
            }
        }
        
        [[UIViewUtil firstAvailableUIViewControllerWithView:self] presentModalViewController:pickerController animated:YES];
        [pickerController release];

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [picker dismissModalViewControllerAnimated:YES];
    
    NSString* mediaType=[info objectForKey:UIImagePickerControllerMediaType];
    if([mediaType isEqualToString:(NSString*)kUTTypeImage])//@"public.image"
    {
        UIImage* image=[info objectForKey:UIImagePickerControllerEditedImage];
        iPortraitImageView.image=image;
    }


后面再次测试,结果测试每次拍照:

UIImage* image=[info objectForKey:UIImagePickerControllerOriginalImage];
UIImageOrientation imageOrientation=image.imageOrientation;

imageOrientation的值如左列,拍照时home键在位置为右列的值

UIImageOrientationRight 下
UIImageOrientationUp    右
UIImageOrientationDown  左
UIImageOrientationLeft 上

若拍照多次后,出现黑屏,检查是否有打印内容警告,同时看是否有上一次的拍照的图片没释放。


参考。。。。

https://gist.github.com/1531596



13. 对nil的image.size.width取值,结果可能不确定。可能在大多数机器上取值为0,而有的机器上取到的是不确定值。

      所以一定要判断如果为nil,width取值0。

14.用图片填充backgroundColor时,图片上的透明区域可能为成为黑色。backgroundColor是随内容大小而铺的。

 

15.在资源目录中,如果同时存在Icon.png 114x114像素,Icon@2x.png 114x114像素

[image imageNamed:@"Icon.png"]; 尺寸是114点,使用的图片是Icon.png,像素/点为1:1
 NSString* path=[[NSBundle mainBundle ] pathForResource:@"Icon" ofType:@"png"];
[UIImage imageWithContentsOfFile:path];尺寸是114点,使用的图片是Icon.png,像素/点为1:1
path=[[NSBundle mainBundle ] pathForResource:@"Icon@2x" ofType:@"png"];
[UIImage imageWithContentsOfFile:path];尺寸是57点,使用的图片是Icon@2x.png,像素/点为2:1

在Documents中时,imageWithContentsOfFile的结果同上。

看样子,对文件名中的@2x的识别,是UIImage在根据路径找图片后本身完成的,并且它是看最后使用的图片名,而不一定是在路径中指定的。

[NSData dataWithContentsOfFile:path]和[UIImage imageWithData:data],对于Icon.png和Icon@2x.png,尺寸都是114点,像素/点为1:1。

图片也可以按目录分组使用,[ [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@“目录名”] stringByAppendingPathComponent:@“img1.png”],

然后用[UIImage imageWithContentsOfFile:path]加载。

但图片要使用资源文件夹方式管理。


16.图片圆角化

     http://www.cocoachina.com/bbs/read.php?tid=1757&page=1


17. 给图片加滤镜

      用Core Graphic的API,把图片解析成RGBA四通道的位图放入内存, 然后内存中有一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),改变RGB的数值,再写回去重新生成。

      变为黑白照片就是把每个像素点的RGB的值相加求平均值,再回写回去。例如:R=B=G=100,就是灰色的,写 for循环把每个像素点的RGB都改成各自的平均值,照片就变为黑白色了。如果图像变为怀旧照片,就是底色发黄的,就是RG的比值调高,B保持不变,因为红绿相配就是黄色。
      借助Android里的ColorMatrix(颜色矩阵)的概念,重要的就是把每个像素点的RGB调整为新值。

      http://www.cocoachina.com/bbs/read.php?tid=69525

      http://www.cnblogs.com/leon19870907/articles/1978065.html


18.   绘半透明矩形
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(ctx,[[UIColor blackColor] colorWithAlphaComponent:0.5].CGColor);
        CGContextAddRect(ctx, CGRectMake(0, 0, 320, 44));
        CGContextClosePath(ctx);
        CGContextDrawPath(ctx, kCGPathFill);


19.  GPUImage

       https://github.com/BradLarson/GPUImage

       先编译framework目录下GPUImage.xcodeproj,生成.a,再编译examples下某个应用程序。

    

 20.给UIView拍照

     基本原理是将UIView的layer描绘到图形上下文。
  #import "QuartzCore/CALayer.h"
 UIView全局拍照
- (UIImage *) imageFromView:(UIView *)view
 {
    UIImage *screenImage;
    UIGraphicsBeginImageContext(view.frame.size);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    screenImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return screenImage;
}
 
UIView局域拍照
- (UIImage *) imageFromView:(UIView *)view rect:(CGRect)rect
{
    CGPoint pt = rect.origin;
    UIImage *screenImage;
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextConcatCTM(context,  CGAffineTransformMakeTranslation(-(int)pt.x, -(int)pt.y));
    [view.layer renderInContext:context];
    screenImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return screenImage;
}
参考 http://bj007.blog.51cto.com/1701577/533632



      UIImagePickerControllerSourceTypePhotoLibrary:表示显示所有的照片

      UIImagePickerControllerSourceTypeCamera:表示从摄像头选取照片

      UIImagePickerControllerSourceTypeSavedPhotosAlbum:表示仅仅从相册中选取照片。


21.BradLarson / GPUImage 图像处理开源代码

     GPUImage是个功能十分强大、又十分易用的图像处理库。提供各种各样的图像处理滤镜,并且支持照相机和摄像机的实时滤镜。GPUImage顾名思义,是基于GPU的图像加速,所以图像处理速度十分快,并且能够自定义图像滤镜。支持ARC。 [Code4App.com]


22.iOS中使用blend改变图片颜色

http://onevcat.com/2013/04/using-blending-in-ios/
http://blog.csdn.net/ricky1217/article/details/8591827

 类似资料: