在一開始拿到這個項目的時候, 我是覺得很輕松的,以前做工PHP的驗證碼生成和自動識別項目,很輕松完成惦费。想必是當(dāng)時的php庫比較的完善吧趟脂,也有可能當(dāng)時涉及的比較淺泰讽,壓根沒有機會去觸及較深層的知識。這次花了好幾天的時間去解決一個問題還是沒解決掉昔期,讓我感觸頗深已卸。在國內(nèi)論壇發(fā)帖也沒有人回,最后還是在stackoverflow(問題鏈接)上發(fā)帖有兩個大神一語道破天機硼一,還附上了apple開發(fā)者檔案的解決方法累澡,才讓度過了一個難關(guān)。特此把自己覺得有用的東西寫在這里般贼,大家一起共勉愧哟。
問題1
用Photoshop生成的一張純紅色圖,設(shè)置的顏色是(238,42,43)但是到最后按Apple開發(fā)者文檔提到的方法取到的顏色是(231, 17,33), 查了很多東西哼蛆,應(yīng)該都沒有錯蕊梧,于是繼續(xù)厚著臉皮求教大神。
大神回復(fù)
Re the color issue, I just created an image in Photoshop with 238, 42, 43 and when I processed it like shown above, in my app I saw 238, 42, 43. I suspect that there's some colorspace inconsistency or something like that. I'd first open up the JPG again, and confirm that the values weren't altered in the export process or something like that.
所以我就按大神的方法用別的軟件再一次取了色看用photoshop生成的圖片的RGB值腮介。結(jié)果肥矢!結(jié)果!真的如大神所言萤厅,圖像倒出來顏色就變了橄抹。有問題的是圖像本身,而不是程序惕味!
另一大神直接給了一個鏈接
Take a look at this answer and the linked article.
這的是獲益匪淺啊??楼誓!
問題2
為什么之前獲取RGB的方法會發(fā)生錯誤?
之前取色錯誤的圖片的 BitmapInfo.RawValue
是 8194 也就是
CGBitmapInfo.ByteOrder32Little.RawValue | CGImageAlphaInfo.PremultipliedFirst.rawValue
而正確的圖片的BitmapInfo.RawValue 是 5
也就是說不同的BitmapInfo導(dǎo)致了顏色提取的錯誤
Apple開發(fā)者文檔中關(guān)于 BitmapInfo
內(nèi)容中文翻譯
字節(jié)序的相關(guān)博客
Big Endian 和 Little Endian
那么最關(guān)心的問題來了 該怎么解決呢名挥?
Apple 開發(fā)者文檔QA的OC代碼
void ManipulateImagePixelData(CGImageRef inImage){
// Create the bitmap context CGContextRef cgctx = CreateARGBBitmapContext(inImage);
if (cgctx == NULL) {
// error creating context
return;
}
// Get image width, height. We'll use the entire image.
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
// Draw the image to the bitmap context. Once we draw, the memd dory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space. CGContextDrawImage(cgctx, rect, inImage); // Now we can get a pointer to the image data associated with the bitmap // context. void *data = CGBitmapContextGetData (cgctx); if (data != NULL) { // **** You have a pointer to the image data **** // **** Do stuff with the data here **** } // When finished, release the context CGContextRelease(cgctx); // Free image data memory for the context if (data) { free(data); }}CGContextRef CreateARGBBitmapContext (CGImageRef inImage){ CGContextRef context = NULL; CGColorSpaceRef colorSpace; void * bitmapData; int bitmapByteCount; int bitmapBytesPerRow; // Get image width, height. We'll use the entire image. size_t pixelsWide = CGImageGetWidth(inImage); size_t pixelsHigh = CGImageGetHeight(inImage); // Declare the number of bytes per row. Each pixel in the bitmap in this // example is represented by 4 bytes; 8 bits each of red, green, blue, and // alpha. bitmapBytesPerRow = (pixelsWide * 4); bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); // Use the generic RGB color space. colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); if (colorSpace == NULL) { fprintf(stderr, "Error allocating color space\n"); return NULL; } // Allocate memory for image data. This is the destination in memory // where any drawing to the bitmap context will be rendered. bitmapData = malloc( bitmapByteCount ); if (bitmapData == NULL) { fprintf (stderr, "Memory not allocated!"); CGColorSpaceRelease( colorSpace ); return NULL; } // Create the bitmap context. We want pre-multiplied ARGB, 8-bits // per component. Regardless of what the source image format is // (CMYK, Grayscale, and so on) it will be converted over to the format // specified here by CGBitmapContextCreate. context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, // bits per component bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst); if (context == NULL) { free (bitmapData); fprintf (stderr, "Context not created!"); } // Make sure and release colorspace before returning CGColorSpaceRelease( colorSpace ); return context;}