iOS,图片处理

时间:2022-09-29 14:54:10

1.旋转图片

2.缩放图片

3.截取图片指定区域

4.祛除图片白色背景,弄成透明png

5.将UIView转化为UIImage,并转化为data和base64

6.将视频一帧(CMSampleBufferRef)转换为UIImage

7.使用UIWebView加载gif动态图

8.实现图片(UIImage)圆角

9.图片加印章图

10.图片压缩到指定大小

旋转图片

//给定角度旋转图片

-(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation

{

long double rotate = 0.0;

CGRect rect;

float translateX = 0;

float translateY = 0;

float scaleX = 1.0;

float scaleY = 1.0;

switch (orientation) {

case UIImageOrientationLeft:

rotate = M_PI_2;

rect = CGRectMake(0, 0, image.size.height, image.size.width);

translateX = 0;

translateY = -rect.size.width;

scaleY = rect.size.width/rect.size.height;

scaleX = rect.size.height/rect.size.width;

break;

case UIImageOrientationRight:

rotate = 3 * M_PI_2;

rect = CGRectMake(0, 0, image.size.height, image.size.width);

translateX = -rect.size.height;

translateY = 0;

scaleY = rect.size.width/rect.size.height;

scaleX = rect.size.height/rect.size.width;

break;

case UIImageOrientationDown:

rotate = M_PI;

rect = CGRectMake(0, 0, image.size.width, image.size.height);

translateX = -rect.size.width;

translateY = -rect.size.height;

break;

default:

rotate = 0.0;

rect = CGRectMake(0, 0, image.size.width, image.size.height);

translateX = 0;

translateY = 0;

break;

}

UIGraphicsBeginImageContext(rect.size);

CGContextRef context = UIGraphicsGetCurrentContext();

//做CTM变换

CGContextTranslateCTM(context, 0.0, rect.size.height);

CGContextScaleCTM(context, 1.0, -1.0);

CGContextRotateCTM(context, rotate);

CGContextTranslateCTM(context, translateX, translateY);

CGContextScaleCTM(context, scaleX, scaleY);

//绘制图片

CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);

UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();

return newPic;

}

缩放图片

//按比例缩放,size 是你要把图显示到 多大区域 CGSizeMake(980, 560)

-(UIImage *) imageCompressForSize:(UIImage *)sourceImage targetSize:(CGSize)size{

UIImage *newImage = nil;

CGSize imageSize = sourceImage.size;

CGFloat width = imageSize.width;

CGFloat height = imageSize.height;

CGFloat targetWidth = size.width;

CGFloat targetHeight = size.height;

CGFloat scaleFactor = 0.0;

CGFloat scaledWidth = targetWidth;

CGFloat scaledHeight = targetHeight;

CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);

if(CGSizeEqualToSize(imageSize, size) == NO){

CGFloat widthFactor = targetWidth / width;

CGFloat heightFactor = targetHeight / height;

if(widthFactor > heightFactor){

scaleFactor = widthFactor;

}

else{

scaleFactor = heightFactor;

}

scaledWidth = width * scaleFactor;

scaledHeight = height * scaleFactor;

if(widthFactor > heightFactor){

thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;

}else if(widthFactor < heightFactor){

thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;

}

}

UIGraphicsBeginImageContext(size);

CGRect thumbnailRect = CGRectZero;

thumbnailRect.origin = thumbnailPoint;

thumbnailRect.size.width = scaledWidth;

thumbnailRect.size.height = scaledHeight;

[sourceImage drawInRect:thumbnailRect];

newImage = UIGraphicsGetImageFromCurrentImageContext();

if(newImage == nil){

NSLog(@"scale image fail");

}

UIGraphicsEndImageContext();

return newImage;

}

截取图片指定区域

CGRect rect=CGRectMake(0, 0, 100, 100);

//截取图片指定区域

img=[UIImage imageWithCGImage:CGImageCreateWithImageInRect(img.CGImage, rect)];

祛除图片白色背景,弄成透明png

//颜色变化

void ProviderReleaseData (void *info, const void *data, size_t size)

{

free((void*)data);

}

//将签名不要的背景色转换

- (UIImage*) imageBlackToTransparent:(UIImage*) image

{

// 分配内存

const int imageWidth = image.size.width;

const int imageHeight = image.size.height;

size_t      bytesPerRow = imageWidth * 4;

uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);

// 创建context

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,

kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);

CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);

// 遍历像素

int pixelNum = imageWidth * imageHeight;

uint32_t* pCurPtr = rgbImageBuf;

for (int i = 0; i < pixelNum; i++, pCurPtr++)

{

//把绿色变成黑色,把背景色变成透明

if ((*pCurPtr & 0x65815A00) == 0x65815a00)    // 将背景变成透明

{

uint8_t* ptr = (uint8_t*)pCurPtr;

ptr[0] = 0;

}

else if ((*pCurPtr & 0x00FF0000) == 0x00ff0000)    // 将绿色变成黑色

{

uint8_t* ptr = (uint8_t*)pCurPtr;

ptr[3] = 0; //0~255

ptr[2] = 0;

ptr[1] = 0;

}

else if ((*pCurPtr & 0xFFFFFF00) == 0xffffff00)    // 将白色变成透明

{

uint8_t* ptr = (uint8_t*)pCurPtr;

ptr[0] = 0;

}

else

{

// 改成下面的代码,会将图片转成想要的颜色

uint8_t* ptr = (uint8_t*)pCurPtr;

ptr[3] = 0; //0~255

ptr[2] = 0;

ptr[1] = 0;

}

}

// 将内存转成image

CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);

CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace,

kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,

NULL, true, kCGRenderingIntentDefault);

CGDataProviderRelease(dataProvider);

UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];

// 释放

CGImageRelease(imageRef);

CGContextRelease(context);

CGColorSpaceRelease(colorSpace);

return resultUIImage;

}

将UIView转化为UIImage,并转化为data和base64

//将UIView转化为UIImage

-(UIImage *)createImageFromView:(UIView *)view{

//屏幕密度

CGFloat scale=[UIScreen mainScreen].scale;

//开始绘图,区域大小,半透明效果,屏幕密度

UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, scale);

[view.layer renderInContext:UIGraphicsGetCurrentContext()];

//开始生成图片

UIImage *image=UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return  image;

}

//确定签名事件

-(void)okAction:(UIButton *)sender{

[self.touchView.cleanBtn removeFromSuperview];

//将有签名的视图转化为img并获取data

UIImage *img=[self createImageFromView:self.touchView];

NSData *data=UIImageJPEGRepresentation(img, 80.0f);

//将data转化为base64字符串

NSString *base64Str=[data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

NSString *utf8Str=[NSString stringWithUTF8String:[base64Str UTF8String]];

//base64转UIImage

NSData *dataUtf8=[[NSData alloc] initWithBase64EncodedString:utf8Str options:NSDataBase64DecodingIgnoreUnknownCharacters];

UIImage *base64Image=[UIImage imageWithData:dataUtf8];

}

 
 将视频一帧(CMSampleBufferRef)转换为UIImage
 
 //用AVFoundation捕捉视频帧,很多时候需要把某一帧转换成UIImage,用此函数:

- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer {

// 为媒体数据设置一个CMSampleBuffer的Core Video图像缓存对象

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

// 锁定pixel buffer的基地址

CVPixelBufferLockBaseAddress(imageBuffer, 0);

// 得到pixel buffer的基地址

void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);

// 得到pixel buffer的行字节数

size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

// 得到pixel buffer的宽和高

size_t width = CVPixelBufferGetWidth(imageBuffer);

size_t height = CVPixelBufferGetHeight(imageBuffer);

// 创建一个依赖于设备的RGB颜色空间

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

// 用抽样缓存的数据创建一个位图格式的图形上下文(graphics context)对象

CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,

bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

// 根据这个位图context中的像素数据创建一个Quartz image对象

CGImageRef quartzImage = CGBitmapContextCreateImage(context);

// 解锁pixel buffer

CVPixelBufferUnlockBaseAddress(imageBuffer,0);

// 释放context和颜色空间

CGContextRelease(context);

CGColorSpaceRelease(colorSpace);

// 用Quartz image创建一个UIImage对象image

UIImage *image = [UIImage imageWithCGImage:quartzImage];

// 释放Quartz image对象

CGImageRelease(quartzImage);

return (image);

}

当然,先不要急,因为捕捉到得帧是YUV颜色通道的,这种颜色通道无法通过以上函数转换,RGBA颜色通道才可以成功转换,所以,先需要把视频帧的输出格式设置一下:

[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];

使用UIWebView加载gif动态图

//使用UIWebView加载gif动态图

UIWebView *webView=[[UIWebView alloc] initWithFrame:self.view.frame];

//读取图片

NSString *retinaPath = [[NSBundle mainBundle] pathForResource:@"ker" ofType:@"gif"];

//图片转换为data

NSData *data = [NSData dataWithContentsOfFile:retinaPath];

[webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];

[self.view addSubview:webView];

实现图片(UIImage)圆角

/**

设置图片圆角方法

@param image 原图片

@param radius 圆角度数

@param rect 新图片frame

@return 返回圆角图片

*/

-(UIImage *)makeRoundedImage:(UIImage *) image

radius: (float) radius cgRect:(CGRect)rect;

{

CALayer *imageLayer = [CALayer layer];

imageLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);

imageLayer.contents = (id) image.CGImage;

imageLayer.masksToBounds = YES;

imageLayer.cornerRadius = radius;

UIGraphicsBeginImageContext(rect.size);

[imageLayer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return roundedImage;

}

图片加印章图

#pragma mark - 加图片印章(可以用半透明图片形成水印效果)

- (UIImage *)imageWithTransImage:(UIImage *)useImage addtransparentImage:(UIImage *)transparentimg

{

UIGraphicsBeginImageContext(useImage.size);

[useImage drawInRect:CGRectMake(0, 0, useImage.size.width, useImage.size.height)];

//印章图片位置大小

[transparentimg drawInRect:CGRectMake(useImage.size.width - useImage.size.width*0.18 - 10, 10, useImage.size.width*0.18, useImage.size.height*0.26)];

UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return resultingImage;

}

图片压缩到指定大小

#pragma mark -压缩图片到指定大小(单位KB)

- (NSData *)compressImage:(UIImage *)image toMaxFileSize:(NSInteger)maxFileSize{

CGFloat compression = 0.9f;

CGFloat maxCompression = 0.1f;

NSData *imageData = UIImageJPEGRepresentation(image, compression);

while ([imageData length] / 1000 > maxFileSize && compression > maxCompression) {

compression -= 0.1;

imageData = UIImageJPEGRepresentation(image, compression);

}

return imageData;

}