美文网首页iOS图片处理iOS UI相关ios
iOS如何简单进行位图图像处理

iOS如何简单进行位图图像处理

作者: Alfred_小乐 | 来源:发表于2017-03-09 15:25 被阅读1468次

    首先什么是位图?
    ****位图图像(bitmap), 亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的(百度百科)。****


    由于在iOS开发中使用的位图大部分是32位RGBA模式,所以我们之说下这种模式的简单图像处理。
    首先我们需要知道什么是32位RGBA模式的位图。32位就表示一个这种模式位图的一个像素所占内存为32位,也就是4个字节的长度。R、G、B、A分别代表red,green,blue和alpha,也就是颜色组成的三原色与透明度值。RGBA每一个占用一个字节的内存。
    知道了上面这些,我们就有了思路:通过改变每一个像素中的RGBA值来进行一些位图图像的处理了。


    首先我们试着把下面这张图转化为一张红色的图。

    原图

    我们首先了解一下CGImageRef的结构

     CGImageRef CGImageCreate (
     
     size_t width, //图片的宽度
     
     size_t height, //图片的高度
     
     size_t bitsPerComponent, //图片每个颜色的bits
     
     size_t bitsPerPixel, //每一个像素占用的buts,15 位24位 32位等等
     
     size_t bytesPerRow, //每一行占用多少bytes 注意是bytes不是bits  1byte = 8bit
     
     CGColorSpaceRef colorspace, //颜色空间,比如rgb
     
     CGBitmapInfo bitmapInfo, //layout ,像素中bit的布局, 是rgba还是 argb
     
     CGDataProviderRef provider, //数据源提供者,url或者内存...
     
     const CGFloat decode[], //一个解码数组
     
     bool shouldInterpolate, //抗锯齿参数
     
     CGColorRenderingIntent intent //图片渲染相关参数
     
     }
    

    了解了image的效果我们就可以撸代码了

    - (void)HandleImage:(UIImage *)img complite:(void(^)(UIImage *img))complite
    {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        CGImageRef imgref = img.CGImage;
        size_t width = CGImageGetWidth(imgref);
        size_t height = CGImageGetHeight(imgref);
        size_t bitsPerComponent = CGImageGetBitsPerComponent(imgref);
        size_t bitsPerPixel = CGImageGetBitsPerPixel(imgref);
        size_t bytesPerRow = CGImageGetBytesPerRow(imgref);
        
        CGColorSpaceRef colorSpace = CGImageGetColorSpace(imgref);
        CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imgref);
        
        bool shouldInterpolate = CGImageGetShouldInterpolate(imgref);
        
        CGColorRenderingIntent intent = CGImageGetRenderingIntent(imgref);
        
        CGDataProviderRef dataProvider = CGImageGetDataProvider(imgref);
        
        CFDataRef data = CGDataProviderCopyData(dataProvider);
        
        UInt8 *buffer = (UInt8*)CFDataGetBytePtr(data);//Returns a read-only pointer to the bytes of a CFData object.// 首地址
        NSUInteger  x, y;
        // 像素矩阵遍历,改变成自己需要的值
        for (y = 0; y < height; y++) {
            for (x = 0; x < width; x++) {
                UInt8 *tmp;
                tmp = buffer + y * bytesPerRow + x * 4;
                UInt8 alpha;
                alpha = *(tmp + 3);
                if (alpha) {// 透明不处理 其他变成红色
                    *tmp = 255;//red
                    *(tmp + 1) = 0;//green
                    *(tmp + 2) = 0;// Blue
                }
            }
        }
        
        CFDataRef effectedData = CFDataCreate(NULL, buffer, CFDataGetLength(data));
        
        CGDataProviderRef effectedDataProvider = CGDataProviderCreateWithCFData(effectedData);
        // 生成一张新的位图
        CGImageRef effectedCgImage = CGImageCreate(
                                                   width, height,
                                                   bitsPerComponent, bitsPerPixel, bytesPerRow,
                                                   colorSpace, bitmapInfo, effectedDataProvider,
                                                   NULL, shouldInterpolate, intent);
        
        UIImage *effectedImage = [[UIImage alloc] initWithCGImage:effectedCgImage];
        
        CGImageRelease(effectedCgImage);
        
        CFRelease(effectedDataProvider);
        
        CFRelease(effectedData);
        
        CFRelease(data);
        dispatch_async(dispatch_get_main_queue(), ^{
            if (complite) {
                complite(effectedImage);
            }
        });
    });
    }
    

    这样我们就得到了一张红色的图像

    红色图像

    当然我们还可以改变很多
    我们把这段代码

                UInt8 *tmp;
                tmp = buffer + y * bytesPerRow + x * 4;
                UInt8 alpha;
                alpha = *(tmp + 3);
                if (alpha) {// 透明不处理 其他变成红色
                    *tmp = 255;//red
                    *(tmp + 1) = 0;//green
                    *(tmp + 2) = 0;// Blue
                }
    

    换成

                UInt8 *tmp;
                tmp = buffer + y * bytesPerRow + x * 4;
                UInt8 alpha;
                alpha = *(tmp + 3);
                UInt8 temp = *tmp;// 取red值
                if (alpha) {// 透明不处理 其他变成红色
                    // 将green和blue都改成red的值,获取灰色图
                    *(tmp + 1) = temp;
                    *(tmp + 2) = temp;
                }
    
    灰色图

    相关文章

      网友评论

        本文标题:iOS如何简单进行位图图像处理

        本文链接:https://www.haomeiwen.com/subject/lwvwgttx.html