iOS图片处理2---CGImageRef实例

幽灵图的实例注释

该方法:传入一个图片,返回一个添加了幽灵图片的新图。
- (UIImage )processUsingPixels:(UIImage)inputImage {

    UInt32 * inputPixels; // 一个指针
 /* 
     1、图片先转成位图,等待添加新图片
 */
    CGImageRef inputCGImage = [inputImage CGImage];
    NSUInteger inputWidth = CGImageGetWidth(inputCGImage);
    NSUInteger inputHeight = CGImageGetHeight(inputCGImage);
    // @1 颜色空间
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    NSUInteger bytesPerPixel = 4;
    NSUInteger bitsPerComponent = 8;
    NSUInteger inputBytesPerRow = bytesPerPixel*inputWidth;
    inputPixels = (UInt32 *)calloc(inputWidth * inputHeight, sizeof(UInt32));
    // @2 位图内容
    CGContextRef context = CGBitmapContextCreate(inputPixels, inputWidth, inputHeight,
                                        bitsPerComponent, inputBytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGContextDrawImage(context, CGRectMake(0, 0, inputWidth, inputHeight), inputCGImage);

     /* 
     2、将幽灵图,(提前计算好需要缩放成的大小)转换成位图
   */
    
    UIImage * ghostImage = [UIImage imageNamed:@"ghost"];
    CGImageRef ghostCGImage = [ghostImage CGImage];
    CGFloat ghostImageAspectRatio = ghostImage.size.width / ghostImage.size.height;
    NSInteger targetGhostWidth = inputWidth * 0.25;

    CGSize ghostSize = CGSizeMake(targetGhostWidth, targetGhostWidth / ghostImageAspectRatio);
    CGPoint ghostOrigin = CGPointMake(inputWidth * 0.5, inputHeight * 0.2);
    NSUInteger ghostBytesPerRow = bytesPerPixel * ghostSize.width;
    UInt32 * ghostPixels = (UInt32 *)calloc(ghostSize.width * ghostSize.height, sizeof(UInt32));
    CGContextRef ghostContext = CGBitmapContextCreate(ghostPixels, ghostSize.width, ghostSize.height,
                                                  bitsPerComponent, ghostBytesPerRow, colorSpace,
                                                  kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    CGContextDrawImage(ghostContext, CGRectMake(0, 0, ghostSize.width, ghostSize.height),ghostCGImage);

   /* 
     3、ghost图片在背景图上的起始点像素位置(依照背景图)
   */
    NSUInteger offsetPixelCountForInput = ghostOrigin.y * inputWidth + ghostOrigin.x;
    UInt32 count = 0;
    NSLog(@"%f,%f",ghostSize.width,ghostSize.height);
   /* 
     4、添加(重点!!!!!)
   */
    // 循环遍历整个背景图
    for (NSUInteger j = 0; j < ghostSize.height; j++) {
        for (NSUInteger i = 0; i < ghostSize.width+1; i++) {
        
//          // 新建指针,在ghostSize的位置上,指针指向相对于背景图的ghostSize的位置
            UInt32 * inputPixel = inputPixels + j * inputWidth + i + offsetPixelCountForInput;
            // 获取到背景图上该点的像素值
            UInt32 inputColor = *inputPixel;
        
        
            count++;
//         NSLog(@"%d * %d + %d + %d -1  = %u",i,j,i,j,(unsigned int)count);
            // 新建指针,获取到幽灵图上的对应位置,并指向!
            UInt32 * ghostPixel = ghostPixels + j * (int)ghostSize.width + i;
            // 获取到幽灵图上该点的像素值
            UInt32 ghostColor = 0;
//                NSLog(@"%x",*ghostPixel);
            if (*ghostPixel > 0) {
            
                ghostColor = *ghostPixel;
//              NSLog(@"%x",(unsigned int)ghostColor);
            }
        
        
            // 两个像素值进行合并。
                /*
         每一个颜色都有一个透明通道来标识透明度。并且,你每创建一张图像,每一个像素都会有一个颜色值。
         所以,如果遇到有透明度和半透明的颜色值该如何处理呢?
         答案是,对透明度进行混合。在最顶层的颜色会使用一个公式与它后面的颜色进行混合。公式如下:
         
         NewColor = TopColor * TopColor.Alpha + BottomColor * (1 - TopColor.Alpha)
         当顶层透明度为1时,新的颜色值等于顶层颜色值。
         当顶层透明度为0时,新的颜色值于底层颜色值。
         最后,当顶层的透明度值是0到1之前的时候,新的颜色值会混合借于顶层和底层颜色值之间。
         
         还可以用 premultiplied alpha的方法。

             */
            // 将幽灵图像的每一个像素的透明通道都乘以了0.5,使它成为半透明状态。然后将它混合到图像中
            CGFloat ghostAlpha = 0.5f * (A(ghostColor) / 255.0);
            UInt32 newR = R(inputColor) * (1 - ghostAlpha) + R(ghostColor) * ghostAlpha;
            UInt32 newG = G(inputColor) * (1 - ghostAlpha) + G(ghostColor) * ghostAlpha;
            UInt32 newB = B(inputColor) * (1 - ghostAlpha) + B(ghostColor) * ghostAlpha;
        
            // 将每个颜色的值范围进行限定到0到255之间,以防越界。
            newR = MAX(0,MIN(255, newR));
            newG = MAX(0,MIN(255, newG));
            newB = MAX(0,MIN(255, newB));
        
            // 像素拼接,设置ghostSize位置上的新像素
             *inputPixel = RGBAMake(newR, newG, newB, A(inputColor));
//            inputPixel = NULL;
//            ghostPixel = NULL;
        }
    }


    CGImageRef newCGImage = CGBitmapContextCreateImage(context);
    UIImage * processedImage = [UIImage imageWithCGImage:newCGImage];

    // 5. Cleanup!
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    CGContextRelease(ghostContext);
    CGImageRelease(newCGImage);
    free(inputPixels);
    free(ghostPixels);
    return processedImage;

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,478评论 25 707
  • 看完《温州一家人》这本小说,感触颇深,对温州人更加由衷的佩服,也许他们骨子里就流淌着经商的血液。就如同书封...
    冷冷123456阅读 4,034评论 0 3
  • 又是一年秋收季,又是一年开学季。于是想到了校园、想到了未曾谋面的可爱孩子们,心中有期待、有压力、有畅想、有...
    唯美儿阅读 566评论 0 2
  • 开源2d游戏引擎,由cocos2d-objc演化而来的纯swift版本,Fiber2D开源地址:https://g...
    工匠良辰阅读 442评论 0 0