一,截图一般需要用到两大功能:全屏截图和指定区域截图。
二,拿到一些图片,需要对图片进行合成的时候,外层图片的底色会很讨厌,我们需要把那层讨厌的颜色去掉,换成透明的,或者指定的某种颜色。比如我们代码生成的二维码图片,默认出来就是白色底,但是将该二维码和展示公司形象的图片组合的时候,那张白色底在很显眼,最好是给换成透明的。
全屏截图需要考虑的是当前界面是否有导航栏,指定区域截图需要考虑的是当前手机屏幕对图片的缩放比例。
修改图片的颜色,其实是遍历该image的每个像素点,然后找到对应的ARGB进行值替换。
/**
* 将图片中的指定颜色转换为透明
*/
- (UIImage *)imageToTransparentWithOriginalColor:(UIColor *)originalColor {
// 分解原来的颜色
CGFloat red = 0.0;
CGFloat green = 0.0;
CGFloat blue = 0.0;
CGFloat alpha = 0.0;
[originalColor getRed:&red green:&green blue:&blue alpha:&alpha];
// 分配内存
const int imageWidth = self.size.width;
const int imageHeight = self.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), self.CGImage);
// 遍历像素
int pixelNum = imageWidth * imageHeight;
uint32_t* pCurPtr = rgbImageBuf;
for (int i = 0; i < pixelNum; i++, pCurPtr++) {
//将像素点转成子节数组来表示---第一个表示透明度即ARGB这种表示方式。ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
//分别取出RGB值后。进行判断需不需要设成透明。
uint8_t* ptr = (uint8_t *)pCurPtr;
// NSLog(@"1是%d,2是%d,3是%d",ptr[1],ptr[2],ptr[3]);
if(ptr[1] == red * 255 || ptr[2] == green * 255 || ptr[3] == blue * 255) {
ptr[0] = 0;
}
}
// 将内存转成image
CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil);
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;
}
/**
* 将图片中的指定颜色转换为新的颜色
*
* @pram originalColor 原来的颜色
* @pram newColor 新的颜色
*/
- (UIImage *)imageOriginalColor:(UIColor *)originalColor toNewColor:(UIColor *)newColor {
// 分解原来的颜色
CGFloat red1 = 0.0;
CGFloat green1 = 0.0;
CGFloat blue1 = 0.0;
CGFloat alpha1 = 0.0;
CGFloat red2 = 0.0;
CGFloat green2 = 0.0;
CGFloat blue2 = 0.0;
CGFloat alpha2 = 0.0;
[originalColor getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
[newColor getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];
// 分配内存
const int imageWidth = self.size.width;
const int imageHeight = self.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), self.CGImage);
// 遍历像素
int pixelNum = imageWidth * imageHeight;
uint32_t* pCurPtr = rgbImageBuf;
for (int i = 0; i < pixelNum; i++, pCurPtr++) {
// 将像素点转成子节数组来表示---第一个表示透明度即ARGB这种表示方式。
// ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
uint8_t* ptr = (uint8_t *)pCurPtr;
if (ptr[0] == alpha1) ptr[0] = alpha2;
if (ptr[1] == red1 * 255) ptr[1] = red2 * 255;
if (ptr[2] == green1 * 255) ptr[2] = green2 * 255;
if (ptr[3] == blue1 * 255) ptr[3] = blue2 * 255;
}
// 将内存转成image
CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil);
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;
}
/**
* 全屏截图
*/
+ (UIImage *)screenShot {
return [self screenShotWithRect:[UIApplication sharedApplication].keyWindow.bounds isNavigation:NO];
}
/**
* 屏幕截图
*
* @pram rect 截图的frame
* @pram isNavigation 导航栏是否显示
*/
+ (UIImage *)screenShotWithRect:(CGRect)rect isNavigation:(BOOL)isNavigation {
// 获取屏幕放大比例
CGFloat scale = [UIScreen mainScreen].scale;
CGRect newRect = rect;
newRect.size.width *= scale;
newRect.size.height *= scale;
CGFloat height = 0;
if (isNavigation) {
height = NavigationViewHeight;
}
newRect.origin.y += height;
newRect.origin.x *= scale;
newRect.origin.y *= scale;
// 设置截屏大小
UIGraphicsBeginImageContextWithOptions(CGSizeMake(newRect.size.width, newRect.size.height), YES, 0);
[[UIApplication sharedApplication].keyWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = viewImage.CGImage;
// 设置截图的区域
CGImageRef imageRefRect = CGImageCreateWithImageInRect(imageRef, newRect);
UIImage *sendImage = [[UIImage alloc] initWithCGImage:imageRefRect];
// 保存图片到照片库
// UIImageWriteToSavedPhotosAlbum(sendImage, nil, nil, nil);
return sendImage;
}
/**
* 返回截取到的图片数据类型
*/
+ (NSData *)dataWithScreenshot {
UIImage *image = [self imageWithScreenshot];
UIGraphicsEndImageContext();
return UIImagePNGRepresentation(image);
}
/**
* 截取当前屏幕
*/
+ (UIImage *)imageWithScreenshot {
CGSize imageSize = CGSizeZero;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsPortrait(orientation))
imageSize = [UIScreen mainScreen].bounds.size;
else
imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
CGContextSaveGState(context);
CGContextTranslateCTM(context, window.center.x, window.center.y);
CGContextConcatCTM(context, window.transform);
CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
if (orientation == UIInterfaceOrientationLandscapeLeft) {
CGContextRotateCTM(context, M_PI_2);
CGContextTranslateCTM(context, 0, -imageSize.width);
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -imageSize.height, 0);
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
CGContextRotateCTM(context, M_PI);
CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
}
if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
} else {
[window.layer renderInContext:context];
}
CGContextRestoreGState(context);
}
return UIGraphicsGetImageFromCurrentImageContext();
}
网友评论