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;

}

你可能感兴趣的:(iOS图片处理2---CGImageRef实例)