年前产品经理脑袋抽筋,要做夜间模式。做了一下技术预演,然后就开干了。
找到了网上最火的夜间开源框架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