CGImage von Byte-Array
Frage
ein CGImage oder NSImage aus einer Datei Laden ein Standard-Bildformat (JPEG, GIF, PNG et.) Ist alles sehr einfach.
Allerdings habe ich jetzt brauche eine CGImage aus einem Array in Bytes im Speicher mit libfreetype erzeugt zu erstellen. Es ist wirklich einfach, OpenGL-Texturen aus einem Array von Bytes formatiert zu erstellen, und ich kann sehen, wie eine CGBitmapContext zu write erstellen. Aber ich kann nicht scheinen, eine einfache Möglichkeit zu finden, ein CGImage aus einem rohen Pixel-Array zu erstellen.
Lösung
Sie können eine CGDataProvider
erstellen, und lassen Sie CG die erforderlichen Daten von Ihrem Provider anfordern, anstatt zu einem Bildpuffer zu schreiben.
Hier ist ein sehr einfaches Beispiel, das eine schwarze CGImage
der Größe erzeugt 64x64.
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);
und getBytes ist wie folgt definiert:
size_t getBytes(void *info, void *buffer, size_t count) {
memset(buffer, 0x00, count);
return count;
}
Natürlich wollen Sie die anderen Rückrufe (skipForward
, rewind
, releaseInfo
), implementieren und eine geeignete Struktur oder ein Objekt für info
verwenden.
Für weitere Informationen besuchen Sie die CGImage und CGDataProvider Referenzen .
Andere Tipps
cfdata Verwendung kann die obige Code einfacher machen. Hier ist der Code.
// 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);
Alte Frage, aber immer noch nützlich! Swift 4 äquivalent chansuk Parks Antwort:
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)