背景
1.在我們的實際開發(fā)工作中隨著項目的深入對于圖片得要求越來高,考慮的外在條件也越來越多
2.我們不在滿足于UI給我圖片我們直接加載顯示在視圖上谎碍,我們需要考慮資源包的大小,圖片的可擴(kuò)展性(機(jī)型的適配)
3.所以在這里給大家分享圖片一些關(guān)于圖片處理的技術(shù)
一且警、圖片截屏處理
1.獲取某個視圖的截屏
- (UIImage *)getScreenRecordingImageWithView:(UIView *)view
{
// 1.設(shè)置獲取畫布大小
UIGraphicsBeginImageContextWithOptions(CGSizeMake(view.frame.size.width, view.frame.size.height), YES, [UIScreen mainScreen].scale);
// [self.layer renderInContext:UIGraphicsGetCurrentContext()];
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:true];
UIImage *screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenshotImage;
}
二岂贩、視圖的顏色處理
1.設(shè)置視圖漸變色效果
- (void)setGradientLayerWithView:(UIView *)view {
// 創(chuàng)建 CAGradientLayer 對象
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
// 設(shè)置 gradientLayer 的 Frame
gradientLayer.frame = view.bounds;
// 創(chuàng)建漸變色數(shù)組,需要轉(zhuǎn)換為CGColor顏色
gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, [UIColor yellowColor].CGColor, (__bridge id)[UIColor redColor].CGColor];
// 設(shè)置三種顏色變化點(diǎn)娱局,取值范圍 0.0~1.0
gradientLayer.locations = @[@(0.0f) ,@(0.2f) ,@(1.0f)];
// 設(shè)置漸變顏色方向,左上點(diǎn)為(0,0), 右下點(diǎn)為(1,1)
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1);
// 添加漸變色到創(chuàng)建的 UIView 上去
[view.layer addSublayer:gradientLayer];
}
2.視圖漸隱效果設(shè)置
// 在很多時候我們?yōu)榱嗽鰪?qiáng)我們的視覺交互效果咧七,往往讓一些視圖在邊界位置有一個漸隱,效果衰齐,
// 例如:很多音樂播放器中歌詞滾出屏幕或者進(jìn)入屏幕時,文字會像切掉一樣很生硬继阻,如果能讓文字出現(xiàn)漸隱效果會更好一些
// 實現(xiàn)思慮:1.UIView的蒙版效果耻涛,蒙版視圖實體和視圖重疊位置顯示,蒙版視圖透明位置和視圖重疊位置隱藏瘟檩,蒙版視圖有透明效果位置和視圖重疊位置alpha = 1.0 - 蒙版視圖.alpha
// 2.使用漸變視圖作為蒙版視圖
- (void)setBoundaryFadeWithView:(UIView *)view {
// 1.獲取一個黑色到透明色漸變色蒙版
UIView *maskView = [[UIView alloc] initWithFrame:view.bounds];
// 創(chuàng)建 CAGradientLayer 對象
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
// 設(shè)置 gradientLayer 的 Frame gradientLayer.frame = view.bounds;
// 創(chuàng)建漸變色數(shù)組抹缕,需要轉(zhuǎn)換為CGColor顏色
gradientLayer.colors = @[[UIColor colorWithWhite:0 alpha:0].CGColor, [UIColor blackColor].CGColor, [UIColor blackColor].CGColor, [UIColor colorWithWhite:0 alpha:0].CGColor];
// 設(shè)置三種顏色變化點(diǎn),取值范圍 0.0~1.0
gradientLayer.locations = @[@(0.0f) ,@(0.1f) ,@(0.9f) ,@(1.0f)];
// 設(shè)置漸變顏色方向墨辛,左上點(diǎn)為(0,0), 右下點(diǎn)為(1,1)
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1);
// 添加漸變色到創(chuàng)建的 UIView 上去
[maskView.layer addSublayer:gradientLayer];
// 2.把maskView作為view的蒙版視圖
view.maskView = maskView;
}
3.獲取任意顏色色的png圖片視圖
- (void)setPNGColorView:(UIView *)view pngImage:(UIImage *)pngImage color:(UIColor *)color {
// 1.設(shè)置視圖的顏色
view.backgroundColor = color;
// 2.創(chuàng)建蒙版
UIImageView *maskView = [[UIImageView alloc] initWithFrame:view.bounds];
maskView.image = pngImage;
view.maskView = maskView;
}
三卓研、iOS繪制鏤空的圖片
// 獲取鏤空的背景圖片,例如我們在日常開發(fā)中添加的各種功能引導(dǎo)視圖背蟆,需要遮罩中漏出需要看到的按鈕或者圖片
- (UIImage*)drawHollowPicture
{
// 01 創(chuàng)建畫布
CGFloat width = [UIScreen mainScreen].bounds.size.width;
CGFloat height = [UIScreen mainScreen].bounds.size.height;
CGRect frame = CGRectMake(0, 0, width, height);
UIGraphicsBeginImageContextWithOptions(frame.size, false, [UIScreen mainScreen].nativeScale);
CGContextRef context = UIGraphicsGetCurrentContext();
// 02 繪制背景顏色
UIColor *bgColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
CGContextSetFillColorWithColor(context, bgColor.CGColor);
CGContextAddRect(context, frame);
CGContextDrawPath(context, kCGPathFill);
// 03 裁剪圓形
// 設(shè)置繪制模式
CGContextSetBlendMode(context, kCGBlendModeClear);
// 畫橢圓
CGContextAddEllipseInRect(context, CGRectMake(10, 10, 60, 60)); //橢圓
CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
CGContextDrawPath(context, kCGPathFill);
// 04 獲取繪制圖片
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}
四、iOS中對圖片進(jìn)行數(shù)字處理的方式
// 1.灰度處理
- (UIImage*)getNewImageWithOldImage:(UIImage*)image {
// 1.定義色值的索引位置
const int RED =0;
const int GREEN =1;
const int BLUE =2;
const int ALPHA =3;
// 2.定義圖片的大小
CGRect imageRect = CGRectMake(0,0, image.size.width* image.scale, image.size.height* image.scale);
int width = imageRect.size.width;
int height = imageRect.size.height;
// 3.創(chuàng)建圖片像素數(shù)組的內(nèi)存大小
uint32_t *pixels = (uint32_t*) malloc(width * height *sizeof(uint32_t));
// 清空像素組里面的內(nèi)容
memset(pixels,0, width * height *sizeof(uint32_t));
// 4.創(chuàng)建色系對象
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// 5.創(chuàng)建一個rgba像素的畫布對象哮幢,像素存放在pixels中
// create a context with RGBA pixels
CGContextRef context = CGBitmapContextCreate(pixels, width, height,8, width *sizeof(uint32_t), colorSpace,kCGImageAlphaPremultipliedLast);
// 6.把圖片繪制到畫布上带膀,并且同步到存放像素內(nèi)容的數(shù)組中
// paint the bitmap to our context which will fill in the pixels array
CGContextDrawImage(context,CGRectMake(0,0, width, height), [image CGImage]);
// 7.遍歷所有的像素點(diǎn)進(jìn)行處理
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// 01 每一個像素點(diǎn)的顏色數(shù)組
uint8_t *rgbaPixel = (uint8_t*) &pixels[y * width + x];
// 02 色彩灰度處理
uint32_t gray = 0.3 * rgbaPixel[RED] +0.59 * rgbaPixel[GREEN] +0.11 * rgbaPixel[BLUE];
// rgbaPixel[RED] = gray;
// rgbaPixel[GREEN] = gray;
// rgbaPixel[BLUE] = gray;
// 03 單一顏色替換成紅色
if (rgbaPixel[RED] == 239 && rgbaPixel[GREEN] == 60 && rgbaPixel[BLUE] == 153) {
rgbaPixel[RED] = 255;
rgbaPixel[GREEN] = 0;
rgbaPixel[BLUE] = 0;
}
}
}
// 8.獲取畫布中的圖片對象
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *resultImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:UIImageOrientationUp];
// 9.釋放對象
// we're done with the context, color space, and pixels
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
CGImageRelease(imageRef);
return resultImage;
}
// 2.亮度和對比度處理
/*
對比度: contrast -1~1
亮度: brightness -1~1
亮度公式:Gray = 0.3*R + 0.59*G + 0.11*B
*/
- (UIImage*)getNewImageWithOldImage:(UIImage*)image
contrast:(CGFloat)contrast
brightness:(CGFloat)brightness {
// 1.定義色值的索引位置
const int RED =0;
const int GREEN =1;
const int BLUE =2;
const int ALPHA =3;
// 2.定義圖片的大小
CGRect imageRect = CGRectMake(0,0, image.size.width* image.scale, image.size.height* image.scale);
int width = imageRect.size.width;
int height = imageRect.size.height;
// 3.創(chuàng)建圖片像素數(shù)組的內(nèi)存大小
uint32_t *pixels = (uint32_t*) malloc(width * height *sizeof(uint32_t));
// 清空像素組里面的內(nèi)容
memset(pixels,0, width * height *sizeof(uint32_t));
// 4.創(chuàng)建色系對象
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// 5.創(chuàng)建一個rgba像素的畫布對象,像素存放在pixels中
// create a context with RGBA pixels
CGContextRef context = CGBitmapContextCreate(pixels, width, height,8, width *sizeof(uint32_t), colorSpace,kCGImageAlphaPremultipliedLast);
// 6.把圖片繪制到畫布上橙垢,并且同步到存放像素內(nèi)容的數(shù)組中
// paint the bitmap to our context which will fill in the pixels array
CGContextDrawImage(context,CGRectMake(0,0, width, height), [image CGImage]);
// 7.設(shè)置亮度和對比度
// 如果當(dāng)前亮度或者對比度發(fā)生變化時修改圖片參數(shù)
if (contrast != 0 && brightness == 0) {
// 01 當(dāng)前只修改了對比度
float ta = 0, tr = 0, tg = 0, tb = 0;
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// 01 每一個像素點(diǎn)的顏色數(shù)組
uint8_t *rgbaPixel = (uint8_t*) &pixels[y * width + x];
ta = rgbaPixel[ALPHA];
tr = rgbaPixel[RED];
tg = rgbaPixel[GREEN];
tb = rgbaPixel[BLUE];
tr = (tr - 127.5) * arctan(contrast) + 127.5;
tg = (tg - 127.5) * arctan(contrast) + 127.5;
tb = (tb - 127.5) * arctan(contrast) + 127.5;
rgbaPixel[RED] = clamp(tr);
rgbaPixel[GREEN] = clamp(tg);
rgbaPixel[BLUE] = clamp(tb);
}
}
} else if (contrast == 0 && brightness != 0) {
// 02 當(dāng)前只修改了亮度
float ta = 0, tr = 0, tg = 0, tb = 0;
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// 01 每一個像素點(diǎn)的顏色數(shù)組
uint8_t *rgbaPixel = (uint8_t*) &pixels[y * width + x];
ta = rgbaPixel[ALPHA];
tr = rgbaPixel[RED];
tg = rgbaPixel[GREEN];
tb = rgbaPixel[BLUE];
tr = tr + 255 * brightness;
tg = tg + 255 * brightness;
tb = tb + 255 * brightness;
rgbaPixel[RED] = clamp(tr);
rgbaPixel[GREEN] = clamp(tg);
rgbaPixel[BLUE] = clamp(tb);
}
}
} else if (contrast != 0 && brightness != 0) {
// 03 當(dāng)前對比度和亮度
float ta = 0, tr = 0, tg = 0, tb = 0;
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
// 01 每一個像素點(diǎn)的顏色數(shù)組
uint8_t *rgbaPixel = (uint8_t*) &pixels[y * width + x];
ta = rgbaPixel[ALPHA];
tr = rgbaPixel[RED];
tg = rgbaPixel[GREEN];
tb = rgbaPixel[BLUE];
tr = (tr - 127.5 * (1 - brightness)) * arctan(contrast) + 127.5 * (1 + brightness);
tg = (tg - 127.5 * (1 - brightness)) * arctan(contrast) + 127.5 * (1 + brightness);
tb = (tb - 127.5 * (1 - brightness)) * arctan(contrast) + 127.5 * (1 + brightness);
rgbaPixel[RED] = clamp(tr);
rgbaPixel[GREEN] = clamp(tg);
rgbaPixel[BLUE] = clamp(tb);
}
}
}
// 8.獲取畫布中的圖片對象
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage *resultImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:UIImageOrientationUp];
// 9.釋放對象
// we're done with the context, color space, and pixels
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
CGImageRelease(imageRef);
return resultImage;
}
// 獲取對比度系數(shù)
float arctan(float value) {
return tan( (45 + 44 * value) / 180 * M_PI);
}
float clamp(float value) {
return value > 255 ? 255 :(value < 0 ? 0 : value);
}
五垛叨、多張圖片合成視頻文件
1.有多張UIImage對象合成視頻文件
- (void)getVideoWithImages:(NSArray *)images
{
// 1.視頻輸出設(shè)置
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:kMoviePath] fileType:AVFileTypeMPEG4 error:&error];
NSParameterAssert(videoWriter);
// 2.視頻寫入設(shè)置
NSDictionary *videoSettings = @{AVVideoCodecKey: AVVideoCodecH264, AVVideoWidthKey: [NSNumber numberWithInt:inRect.size.width], AVVideoHeightKey: [NSNumber numberWithInt:inRect.size.height]};
AVAssetWriterInput* writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
// 3.允許開始寫入視頻
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
// 4.多張圖片寫入視頻文件
int __block frame = 0;
[writerInput requestMediaDataWhenReadyOnQueue:dispatch_queue_create("mediaInputQueue", NULL) usingBlock:^{
@autoreleasepool {
while ([writerInput isReadyForMoreMediaData]) {
@autoreleasepool {
if ([self isRecording] == NO) {
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^{
NSLog(@"Successfully closed video writer");
if (videoWriter.status == AVAssetWriterStatusCompleted) {
NSLog(@"成功");
} else {
NSLog(@"失敗");
}
}];
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
break;
}
CGImageRef imageRef = [self getScreenRecordingImage];
CVPixelBufferRef buffer = (CVPixelBufferRef)[self pixelBufferFromCGImage:imageRef size:inRect.size];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
if (buffer) {
if(![adaptor appendPixelBuffer:buffer withPresentationTime:CMTimeMake(frame, 20)])
NSLog(@"FAIL");
else
CFRelease(buffer);
}
});
frame++;
NSLog(@"%d",frame);
}
}
}
}];
}
更多分享:
Github:https://github.com/zhusiming/
GitBook:https://zhusiming.gitbooks.io/smbook/