2010-02-14 15 views
13

एक मानक छवि प्रारूप (जेपीईजी, जीआईएफ, पीएनजी एट।) का उपयोग कर फ़ाइल से एक CGImage या NSImage लोड करना बहुत आसान है।बाइट सरणी से CGImage

हालांकि, अब मुझे libfreetype का उपयोग करके उत्पन्न स्मृति में बाइट्स में एक सरणी से एक CGImage बनाने की आवश्यकता है। स्वरूपित बाइट्स की एक सरणी से ओपनजीएल बनावट बनाना वास्तव में आसान है, और मैं देख सकता हूं कि पर 0GB38m8Contxt को CGBitmapContext कैसे बनाएं, लिखें। लेकिन मुझे कच्चे पिक्सेल सरणी से CGImage बनाने का आसान तरीका नहीं दिख रहा है।

उत्तर

6

आप CGDataProvider बना सकते हैं, और एक छवि बफर को लिखने के बजाय सीजी को अपने प्रदाता से आवश्यक डेटा का अनुरोध करने दें।

यहां एक बहुत ही सरल उदाहरण है जो आकार 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 संदर्भ देखें।

+1

हेक्टेयर। सही नाक मेरे नाक के नीचे सही था। मेरे डेटा को CFData ऑब्जेक्ट में लपेटना और फिर CGDataProviderCreateWithCFData में लपेटना बहुत आसान लगता है। –

+0

@ChrisBecke - क्या आप मुझे और जानकारी दे सकते हैं? मुझे एक ही समस्या है। – Patricia

9

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); 
+0

मूल नींव एपीआई - सीएफडीटा आदि के साथ यह बात यह है कि वे दिखते हैं कि वे अपरिवर्तनीय डेटा के रेफ गिनती उदाहरणों को ले जाने के लिए डिज़ाइन किए गए हैं। लेकिन व्यवहार में वे नए आवंटन और memcpy बहुत कुछ बनाने लगते हैं। –

+0

CGImageCreate कॉल में रंगस्थान 64 * 3 क्यों है? ऐप्पल दस्तावेज़ों के अनुसार "रंगस्थान = गंतव्य रंग स्थान। इस रंग स्थान में घटकों की संख्या निर्दिष्ट छवि में संख्या के समान होना चाहिए।" आप रंग स्थान के लिए घटकों की संख्या का निर्धारण कैसे कर रहे हैं? – Praxiteles

+0

मैं 64s चर बनाने में सक्षम कैसे हो सकता हूं? – achi

0

पुराना सवाल, लेकिन अभी भी उपयोगी! चांसुक पार्क के उत्तर के बराबर 4 स्विफ्ट:

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) 
संबंधित मुद्दे