• iOS --- 通过CPU实现的简单滤镜效果


    iOS中使用CPU实现滤镜效果的原理很简单, 即将图片转换成像素数据, 然后对每一个像素进行相应的滤镜效果计算, 然后重新得到过滤后的图片.
    CPU滤镜效果代码如下:

    头文件

    //  CPUImageFilterUtil.h
    
    #import 
    #import 
    #import 
    #import 
    
    //LOMO
    static const float colormatrix_lomo[] = {
      1.7f,  0.1f, 0.1f, 0, -73.1f,
      0,  1.7f, 0.1f, 0, -73.1f,
      0,  0.1f, 1.6f, 0, -73.1f,
      0,  0, 0, 1.0f, 0 };
    
    //黑白
    static const float colormatrix_heibai[] = {
      0.8f,  1.6f, 0.2f, 0, -163.9f,
      0.8f,  1.6f, 0.2f, 0, -163.9f,
      0.8f,  1.6f, 0.2f, 0, -163.9f,
      0,  0, 0, 1.0f, 0 };
    //复古
    static const float colormatrix_huajiu[] = {
      0.2f,0.5f, 0.1f, 0, 40.8f,
      0.2f, 0.5f, 0.1f, 0, 40.8f,
      0.2f,0.5f, 0.1f, 0, 40.8f,
      0, 0, 0, 1, 0 };
    
    //哥特
    static const float colormatrix_gete[] = {
      1.9f,-0.3f, -0.2f, 0,-87.0f,
      -0.2f, 1.7f, -0.1f, 0, -87.0f,
      -0.1f,-0.6f, 2.0f, 0, -87.0f,
      0, 0, 0, 1.0f, 0 };
    
    //锐化
    static const float colormatrix_ruise[] = {
      4.8f,-1.0f, -0.1f, 0,-388.4f,
      -0.5f,4.4f, -0.1f, 0,-388.4f,
      -0.5f,-1.0f, 5.2f, 0,-388.4f,
      0, 0, 0, 1.0f, 0 };
    
    
    //淡雅
    static const float colormatrix_danya[] = {
      0.6f,0.3f, 0.1f, 0,73.3f,
      0.2f,0.7f, 0.1f, 0,73.3f,
      0.2f,0.3f, 0.4f, 0,73.3f,
      0, 0, 0, 1.0f, 0 };
    
    //酒红
    static const float colormatrix_jiuhong[] = {
      1.2f,0.0f, 0.0f, 0.0f,0.0f,
      0.0f,0.9f, 0.0f, 0.0f,0.0f,
      0.0f,0.0f, 0.8f, 0.0f,0.0f,
      0, 0, 0, 1.0f, 0 };
    
    //清宁
    static const float colormatrix_qingning[] = {
      0.9f, 0, 0, 0, 0,
      0, 1.1f,0, 0, 0,
      0, 0, 0.9f, 0, 0,
      0, 0, 0, 1.0f, 0 };
    
    //浪漫
    static const float colormatrix_langman[] = {
      0.9f, 0, 0, 0, 63.0f,
      0, 0.9f,0, 0, 63.0f,
      0, 0, 0.9f, 0, 63.0f,
      0, 0, 0, 1.0f, 0 };
    
    //光晕
    static const float colormatrix_guangyun[] = {
      0.9f, 0, 0,  0, 64.9f,
      0, 0.9f,0,  0, 64.9f,
      0, 0, 0.9f,  0, 64.9f,
      0, 0, 0, 1.0f, 0 };
    
    //蓝调
    static const float colormatrix_landiao[] = {
      2.1f, -1.4f, 0.6f, 0.0f, -31.0f,
      -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,
      -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,
      0.0f, 0.0f, 0.0f, 1.0f, 0.0f
    };
    
    //梦幻
    static const float colormatrix_menghuan[] = {
      0.8f, 0.3f, 0.1f, 0.0f, 46.5f,
      0.1f, 0.9f, 0.0f, 0.0f, 46.5f,
      0.1f, 0.3f, 0.7f, 0.0f, 46.5f,
      0.0f, 0.0f, 0.0f, 1.0f, 0.0f
    };
    
    //夜色
    static const float colormatrix_yese[] = {
      1.0f, 0.0f, 0.0f, 0.0f, -66.6f,
      0.0f, 1.1f, 0.0f, 0.0f, -66.6f,
      0.0f, 0.0f, 1.0f, 0.0f, -66.6f,
      0.0f, 0.0f, 0.0f, 1.0f, 0.0f
    };
    
    static const float colormatrixs[][20]={
      {
        0.8f,  1.6f, 0.2f, 0, -163.9f,
        0.8f,  1.6f, 0.2f, 0, -163.9f,
        0.8f,  1.6f, 0.2f, 0, -163.9f,
        0,  0, 0, 1.0f, 0
      },
      {
        0.2f,0.5f, 0.1f, 0, 40.8f,
        0.2f, 0.5f, 0.1f, 0, 40.8f,
        0.2f,0.5f, 0.1f, 0, 40.8f,
        0, 0, 0, 1, 0
      },
      {
        1.9f,-0.3f, -0.2f, 0,-87.0f,
        -0.2f, 1.7f, -0.1f, 0, -87.0f,
        -0.1f,-0.6f, 2.0f, 0, -87.0f,
        0, 0, 0, 1.0f, 0
      },
      {
        4.8f,-1.0f, -0.1f, 0,-388.4f,
        -0.5f,4.4f, -0.1f, 0,-388.4f,
        -0.5f,-1.0f, 5.2f, 0,-388.4f,
        0, 0, 0, 1.0f, 0
      },
      {
        0.6f,0.3f, 0.1f, 0,73.3f,
        0.2f,0.7f, 0.1f, 0,73.3f,
        0.2f,0.3f, 0.4f, 0,73.3f,
        0, 0, 0, 1.0f, 0
      },
      {
        1.2f,0.0f, 0.0f, 0.0f,0.0f,
        0.0f,0.9f, 0.0f, 0.0f,0.0f,
        0.0f,0.0f, 0.8f, 0.0f,0.0f,
        0, 0, 0, 1.0f, 0
      },
      {
        0.9f, 0, 0, 0, 0,
        0, 1.1f,0, 0, 0,
        0, 0, 0.9f, 0, 0,
        0, 0, 0, 1.0f, 0
      },
      {
        0.9f, 0, 0, 0, 63.0f,
        0, 0.9f,0, 0, 63.0f,
        0, 0, 0.9f, 0, 63.0f,
        0, 0, 0, 1.0f, 0
      },
      {
        0.9f, 0, 0,  0, 64.9f,
        0, 0.9f,0,  0, 64.9f,
        0, 0, 0.9f,  0, 64.9f,
        0, 0, 0, 1.0f, 0
      },
      {
        2.1f, -1.4f, 0.6f, 0.0f, -31.0f,
        -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,
        -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,
        0.0f, 0.0f, 0.0f, 1.0f, 0.0f
      },
      {
        0.8f, 0.3f, 0.1f, 0.0f, 46.5f,
        0.1f, 0.9f, 0.0f, 0.0f, 46.5f,
        0.1f, 0.3f, 0.7f, 0.0f, 46.5f,
        0.0f, 0.0f, 0.0f, 1.0f, 0.0f
      },
      {
        1.0f, 0.0f, 0.0f, 0.0f, -66.6f,
        0.0f, 1.1f, 0.0f, 0.0f, -66.6f,
        0.0f, 0.0f, 1.0f, 0.0f, -66.6f,
        0.0f, 0.0f, 0.0f, 1.0f, 0.0f
      }
    };
    
    @interface CPUImageFilterUtil : NSObject
    
    + (UIImage *)imageWithImage:(UIImage *)inImage withColorMatrix:(const float*)f;
    
    @end
    

    实现文件

    //  CPUImageFilterUtil.m
    
    #import CPUImageFilterUtil.h
    
    @implementation CPUImageFilterUtil
    
    // 返回一个使用RGBA通道的位图上下文
    static CGContextRef CreateRGBABitmapContext (CGImageRef inImage)
    {
      CGContextRef context = NULL;
      CGColorSpaceRef colorSpace;
    
      //内存空间的指针,该内存空间的大小等于图像使用RGB通道所占用的字节数。
      void *bitmapData; 
    
      int bitmapByteCount;
      int bitmapBytesPerRow;
    
      //获取横向的像素点的个数
      size_t pixelsWide = CGImageGetWidth(inImage);
      size_t pixelsHigh = CGImageGetHeight(inImage); //纵向
    
      //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit(0-255)的空间
      bitmapBytesPerRow = (int)(pixelsWide * 4); 
      //计算整张图占用的字节数
      bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh);
    
      //创建依赖于设备的RGB通道
      colorSpace = CGColorSpaceCreateDeviceRGB();
    
      //分配足够容纳图片字节数的内存空间
      bitmapData = malloc(bitmapByteCount); 
    
      //创建CoreGraphic的图形上下文,该上下文描述了bitmaData指向的内存空间需要绘制的图像的一些绘制参数  
      context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
    
      //Core Foundation中通过含有Create、Alloc的方法名字创建的指针,需要使用CFRelease()函数释放
      CGColorSpaceRelease( colorSpace );
    
      return context;
    }
    
    // 返回一个指针,该指针指向一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),用无符号的char是因为它正好的取值范围就是0-255
    static unsigned char *RequestImagePixelData(UIImage *inImage)
    {
      CGImageRef img = [inImage CGImage];
      CGSize size = [inImage size];
    
      //使用上面的函数创建上下文
      CGContextRef cgctx = CreateRGBABitmapContext(img); 
    
      CGRect rect = {{0,0},{size.width, size.height}};
    
      //将目标图像绘制到指定的上下文,实际为上下文内的bitmapData。
      CGContextDrawImage(cgctx, rect, img); 
      unsigned char *data = CGBitmapContextGetData (cgctx);
    
      //释放上面的函数创建的上下文
      CGContextRelease(cgctx);
      return data;
    }
    
    static void changeRGBA(int *red,int *green,int *blue,int *alpha, const float* f)//修改RGB的值
    {
      int redV = *red;
      int greenV = *green;
      int blueV = *blue;
      int alphaV = *alpha;
    
      *red = f[0] * redV + f[1] * greenV + f[2] * blueV + f[3] * alphaV + f[4];
      *green = f[0+5] * redV + f[1+5] * greenV + f[2+5] * blueV + f[3+5] * alphaV + f[4+5];
      *blue = f[0+5*2] * redV + f[1+5*2] * greenV + f[2+5*2] * blueV + f[3+5*2] * alphaV + f[4+5*2];
      *alpha = f[0+5*3] * redV + f[1+5*3] * greenV + f[2+5*3] * blueV + f[3+5*3] * alphaV + f[4+5*3];
    
      if (*red > 255)
      {
        *red = 255;
      }
      if(*red < 0)
      {
        *red = 0;
      }
      if (*green > 255)
      {
        *green = 255;
      }
      if (*green < 0)
      {
        *green = 0;
      }
      if (*blue > 255)
      {
        *blue = 255;
      }
      if (*blue < 0)
      {
        *blue = 0;
      }
      if (*alpha > 255)
      {
        *alpha = 255;
      }
      if (*alpha < 0)
      {
        *alpha = 0;
      }
    }
    
    + (UIImage*)imageWithImage:(UIImage*)inImage withColorMatrix:(const float*) f
    {
      unsigned char *imgPixel = RequestImagePixelData(inImage);
      CGImageRef inImageRef = [inImage CGImage];
      GLuint w = (GLuint)CGImageGetWidth(inImageRef);
      GLuint h = (GLuint)CGImageGetHeight(inImageRef);
    
      int wOff = 0;
      int pixOff = 0;
    
      //双层循环按照长宽的像素个数迭代每个像素点
      for(GLuint y = 0;y< h;y++)
      {
        pixOff = wOff;
    
        for (GLuint x = 0; x

    使用方法

    UIImage *originImage = [UIImage imageNamed:@testImage];
    const float *colorMatrix = colormatrix_lomo;
    UIImage *filteredImage = [CPUImageFilterUtil imageWithImage:originImage withColorMatrix:colorMatrix];
  • 相关阅读:
    bzoj3306: 树(dfs序+倍增+线段树)
    bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)
    Codeforces 578B. "Or" Game(思维题)
    bzoj3251: 树上三角形(思维题)
    bzoj2006: [NOI2010]超级钢琴(堆+RMQ)
    bzoj4165: 矩阵(堆+hash)
    bzoj3007: 拯救小云公主(二分+并查集)
    Codeforces 582C. Superior Periodic Subarrays(数学+计数)
    Codeforces 585E. Present for Vitalik the Philatelist(容斥)
    Codeforces 585D. Lizard Era: Beginning(meet in the middle)
  • 原文地址:https://www.cnblogs.com/Li-Sport/p/5948756.html
Copyright © 2020-2023  润新知