美文网首页其它技术点iOS Developer
纠结了一周的位图颜色反转,终于在今天不完美解决

纠结了一周的位图颜色反转,终于在今天不完美解决

作者: vicky1221 | 来源:发表于2017-03-13 17:57 被阅读206次

    年前产品经理脑袋抽筋,要做夜间模式。做了一下技术预演,然后就开干了。

    找到了网上最火的夜间开源框架DKNightVersion,已经完美解决了我们大部分的夜间需求。那么但是问题来了,往往最难解决的就是剩下的90%。

    第一部分比较难解决的地方就是我们的在线做题。在线做题用的是唐巧大神的CoreText, 很佩服唐大神这套框架,从我们做在线做题就一直在用,一直都没有出过问题。直到夜间模式的切换。由于这套框架是在给数据之前对数据格式做的配置,所以在重新drawrect的时候需要读取最新的配置,我的做法是在config的时候给data一个colorpicker,每次更新的时候读取当前需要的color。还算完美的解决了这个问题,有需要这部分代码的可以跟我联系。

    第二部分比较难解决的就是试题中一些公式的颜色的反转,之前没有涉及过图片相关的操作,所以开始了网上的搜索。。 最后找到三篇很不错的文章,一个是http://www.jianshu.com/p/a707e48e5238,另一个是:http://www.jianshu.com/p/c647d7edb301, 还有一个是:http://blog.csdn.net/u012519228/article/details/51491797

    这两个都很详细的讲解了图片的格式和转换原理,了解了原理之后,就开始撸代码了。

    但是图片并没有完美显示。感觉是因为一些图片参数配置的原因,之后又查了一些资料。写了一个位图颜色反转的demo,demo里很完美的反转了图片。以下是代码片段:

    - (UIImage*) grayscale:(UIImage*)anImage {

    CGImageRefimageRef;

    imageRef = anImage.CGImage;

    //const int width = anImage.size.width;

    //const int height = anImage.size.height;

    size_twidth=CGImageGetWidth(imageRef);

    size_theight =CGImageGetHeight(imageRef);

    //ピクセルを構成するRGB各要素が何ビットで構成されている

    size_tbitsPerComponent;

    bitsPerComponent =CGImageGetBitsPerComponent(imageRef);

    //ピクセル全体は何ビットで構成されているか

    size_tbitsPerPixel;

    bitsPerPixel =CGImageGetBitsPerPixel(imageRef);

    //画像の横1ライン分のデータが、何バイトで構成されているか

    size_tbytesPerRow;

    bytesPerRow =CGImageGetBytesPerRow(imageRef);

    //画像の色空間

    CGColorSpaceRefcolorSpace;

    colorSpace =CGImageGetColorSpace(imageRef);

    //画像のBitmap情報

    CGBitmapInfobitmapInfo;

    bitmapInfo =CGImageGetBitmapInfo(imageRef);

    //画像がピクセル間の補完をしているか

    boolshouldInterpolate;

    shouldInterpolate =CGImageGetShouldInterpolate(imageRef);

    //表示装置によって補正をしているか

    CGColorRenderingIntentintent;

    intent =CGImageGetRenderingIntent(imageRef);

    //画像のデータプロバイダを取得する

    CGDataProviderRefdataProvider;

    dataProvider =CGImageGetDataProvider(imageRef);

    //データプロバイダから画像のbitmap生データ取得

    CFDataRefdata;

    UInt8*buffer;

    data =CGDataProviderCopyData(dataProvider);

    buffer = (UInt8*)CFDataGetBytePtr(data);

    //// 1ピクセルずつ画像を処理

    for(NSIntegery =0; y < height; y++) {

    for(NSIntegerx =0; x < width; x++) {

    UInt8*tmp = buffer + y * bytesPerRow + x *4;// RGBAの4つ値をもっているので、1ピクセルごとに*4してずらす

    // RGB値を取得

    UInt8alpha,red,green,blue;

    red = *(tmp +0);

    green = *(tmp +1);

    blue = *(tmp +2);

    alpha = *(tmp +3);

    if(alpha) {

    *(tmp +0) =255- red;

    *(tmp +1) =255- green;

    *(tmp +2) =255- blue;

    }

    }

    }

    //効果を与えたデータ生成

    CFDataRefeffectedData;

    effectedData =CFDataCreate(NULL, buffer,CFDataGetLength(data));

    //効果を与えたデータプロバイダを生成

    CGDataProviderRefeffectedDataProvider;

    effectedDataProvider =CGDataProviderCreateWithCFData(effectedData);

    //画像を生成

    CGImageRefeffectedCgImage;

    UIImage*effectedImage;

    effectedCgImage =CGImageCreate(

    width, height,

    bitsPerComponent, bitsPerPixel, bytesPerRow,

    colorSpace, bitmapInfo, effectedDataProvider,

    NULL, shouldInterpolate, intent);

    effectedImage = [[UIImagealloc]initWithCGImage:effectedCgImage];

    //データの解放

    CGImageRelease(effectedCgImage);

    CFRelease(effectedDataProvider);

    CFRelease(effectedData);

    CFRelease(data);

    returneffectedImage;

    }

    这个用的是一个日本的作者写的,不得不服,很完美。

    然后把代码copy到我的项目里,发现运行闪退。。又开始了一番捉急的debug,找了好久还是找不到原因,后来旁边的同事说你把demo里的图片放进来试试,然后发现很完美的就显示出来了,然后我把这个图片的web url放进来发现还是不行,我在想是不是下载的图片有问题,之后尝试了用系统方法去下载图片,然后发现就没出现闪图,而且图片也很完美的显示出来了。虽然问题解决了 但是还是不明白为什么会这样,如果有遇到相同问题的可以一起讨论。

    总之,上边代码可以做图片反转,还可以对图片做很多其他的操作,可以自己去发掘一下。

    参考资料:http://blog.csdn.net/u012519228/article/details/51491797

    http://www.jianshu.com/p/c647d7edb301

    相关文章

      网友评论

      本文标题:纠结了一周的位图颜色反转,终于在今天不完美解决

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