使用標準圖像格式(jpeg,gif,png等)從文件加載CGImage或NSImage都非常簡單。來自字節數組的CGImage
但是,我現在需要在數組中使用libfreetype生成的內存中的字節數組中創建CGImage。它很容易從一組格式化的字節創建OpenGL紋理,我可以看到如何創建一個CGBitmapContext到,編寫即可。但我似乎無法找到從原始像素數組創建CGImage的簡單方法。
使用標準圖像格式(jpeg,gif,png等)從文件加載CGImage或NSImage都非常簡單。來自字節數組的CGImage
但是,我現在需要在數組中使用libfreetype生成的內存中的字節數組中創建CGImage。它很容易從一組格式化的字節創建OpenGL紋理,我可以看到如何創建一個CGBitmapContext到,編寫即可。但我似乎無法找到從原始像素數組創建CGImage的簡單方法。
您可以創建一個CGDataProvider
,並讓CG向您的提供者請求必要的數據,而不是寫入圖像緩衝區。
下面是一個非常簡單的例子,它生成一個大小爲64x64的黑色CGImage
。
CGDataProviderSequentialCallbacks callbacks;
callbacks.getBytes = getBytes;
CGDataProviderRef provider = CGDataProviderCreateSequential(NULL, &callbacks);
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGImageRef img = CGImageCreate(64, // width
64, // height
8, // bitsPerComponent
24, // bitsPerPixel
64*3, // bytesPerRow
space, // colorspace
kCGBitmapByteOrderDefault, // bitmapInfo
provider, // CGDataProvider
NULL, // decode array
NO, // shouldInterpolate
kCGRenderingIntentDefault); // intent
CGColorSpaceRelease(space);
CGDataProviderRelease(provider);
// use the created CGImage
CGImageRelease(img);
和的getBytes的定義是這樣的:
size_t getBytes(void *info, void *buffer, size_t count) {
memset(buffer, 0x00, count);
return count;
}
當然,你將要實現另一個回調(skipForward
,rewind
,releaseInfo
),並使用適當的結構或對象info
。
欲瞭解更多信息,請參閱CGImage和CGDataProvider參考。
使用CFData可以使上面的代碼更簡單。 這是代碼。
// raw pixel data memory of 64 * 64 pixel size
UInt8 pixelData[64 * 64 * 3];
// fill the raw pixel buffer with arbitrary gray color for test
for(size_t ui = 0; ui < 64 * 64 * 3; ui++)
pixelData[ui] = 210;
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CFDataRef rgbData = CFDataCreate(NULL, pixelData, 64 * 64 * 3);
CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);
CGImageRef rgbImageRef = CGImageCreate(64, 64, 8, 24, 64 * 3, colorspace, kCGBitmapByteOrderDefault, provider, NULL, true, kCGRenderingIntentDefault);
CFRelease(rgbData);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorspace);
// use the created CGImage
CGImageRelease(rgbImageRef);
核心基礎API - CFData等的東西是,它們看起來像它們被設計用來攜帶不可變數據的ref計數實例。但實際上,他們確實似乎創造了新的分配和memcpy很多。 – 2010-09-26 16:46:41
爲什麼CGImageCreate調用中的colorspace 64 * 3?根據Apple文檔「colorspace =目標色彩空間,此色彩空間中的組件數量必須與指定圖像中的數量相同」。你如何確定色彩空間的組件數量? – Praxiteles 2012-12-12 07:51:25
我怎樣才能使64s變量? – achi 2014-07-16 23:59:33
老問題,但仍然有用!雨斯公園回答:
let height = 64
let width = 64
let numComponents = 3
let numBytes = height * width * numComponents
let pixelData = [UInt8](repeating: 210, count: numBytes)
let colorspace = CGColorSpaceCreateDeviceRGB()
let rgbData = CFDataCreate(nil, pixelData, numBytes)!
let provider = CGDataProvider(data: rgbData)!
let rgbImageRef = CGImage(width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8 * numComponents,
bytesPerRow: width * numComponents,
space: colorspace,
bitmapInfo: CGBitmapInfo(rawValue: 0),
provider: provider,
decode: nil,
shouldInterpolate: true,
intent: CGColorRenderingIntent.defaultIntent)!
// Do something with rgbImageRef, or for UIImage:
let outputImage = UIImage(cgImage: rgbImageRef)
ha。正確的功能正好在我的鼻子下面。它看起來很簡單,我的數據包裝在一個CFData對象,然後CGDataProviderCreateWithCFData。 – 2010-02-14 16:14:11
@ChrisBecke - 你能給我更多的信息嗎?我有類似的問題。 – Patricia 2014-07-03 22:37:32