一,截圖一般需要用到兩大功能:全屏截圖和指定區(qū)域截圖桃移。
二屋匕,拿到一些圖片,需要對(duì)圖片進(jìn)行合成的時(shí)候借杰,外層圖片的底色會(huì)很討厭过吻,我們需要把那層討厭的顏色去掉,換成透明的蔗衡,或者指定的某種顏色纤虽。比如我們代碼生成的二維碼圖片,默認(rèn)出來(lái)就是白色底绞惦,但是將該二維碼和展示公司形象的圖片組合的時(shí)候逼纸,那張白色底在很顯眼,最好是給換成透明的济蝉。
全屏截圖需要考慮的是當(dāng)前界面是否有導(dǎo)航欄杰刽,指定區(qū)域截圖需要考慮的是當(dāng)前手機(jī)屏幕對(duì)圖片的縮放比例。
修改圖片的顏色王滤,其實(shí)是遍歷該image的每個(gè)像素點(diǎn)贺嫂,然后找到對(duì)應(yīng)的ARGB進(jìn)行值替換。
/**
* 將圖片中的指定顏色轉(zhuǎn)換為透明
*/
- (UIImage *)imageToTransparentWithOriginalColor:(UIColor *)originalColor {
// 分解原來(lái)的顏色
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];
// 分配內(nèi)存
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);
// 創(chuàng)建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++) {
//將像素點(diǎn)轉(zhuǎn)成子節(jié)數(shù)組來(lái)表示---第一個(gè)表示透明度即ARGB這種表示方式雁乡。ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
//分別取出RGB值后第喳。進(jìn)行判斷需不需要設(shè)成透明。
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;
}
}
// 將內(nèi)存轉(zhuǎn)成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;
}
/**
* 將圖片中的指定顏色轉(zhuǎn)換為新的顏色
*
* @pram originalColor 原來(lái)的顏色
* @pram newColor 新的顏色
*/
- (UIImage *)imageOriginalColor:(UIColor *)originalColor toNewColor:(UIColor *)newColor {
// 分解原來(lái)的顏色
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];
// 分配內(nèi)存
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);
// 創(chuàng)建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++) {
// 將像素點(diǎn)轉(zhuǎn)成子節(jié)數(shù)組來(lái)表示---第一個(gè)表示透明度即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;
}
// 將內(nèi)存轉(zhuǎn)成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 導(dǎo)航欄是否顯示
*/
+ (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;
// 設(shè)置截屏大小
UIGraphicsBeginImageContextWithOptions(CGSizeMake(newRect.size.width, newRect.size.height), YES, 0);
[[UIApplication sharedApplication].keyWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = viewImage.CGImage;
// 設(shè)置截圖的區(qū)域
CGImageRef imageRefRect = CGImageCreateWithImageInRect(imageRef, newRect);
UIImage *sendImage = [[UIImage alloc] initWithCGImage:imageRefRect];
// 保存圖片到照片庫(kù)
// UIImageWriteToSavedPhotosAlbum(sendImage, nil, nil, nil);
return sendImage;
}
/**
* 返回截取到的圖片數(shù)據(jù)類型
*/
+ (NSData *)dataWithScreenshot {
UIImage *image = [self imageWithScreenshot];
UIGraphicsEndImageContext();
return UIImagePNGRepresentation(image);
}
/**
* 截取當(dāng)前屏幕
*/
+ (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();
}