美文网首页其它技术点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