2010-11-07 10 views

उत्तर

19

आप कैलियर प्राप्त करने के लिए दृश्य की परत संपत्ति का उपयोग कर सकते हैं और CoreRraphics संदर्भ में आकर्षित करने के लिए renderInContext का उपयोग कर सकते हैं। आप एक पिक्सेल बफर प्राप्त करने के लिए अपने आप को आवंटित स्मृति के साथ कोरग्राफिक्स संदर्भ सेट अप कर सकते हैं। फिर आप इसे सामान्य विधि से ओपनजीएल में अपलोड कर सकते हैं।

तो: UIView की पिक्सेल सामग्री प्राप्त करने का एक माध्यम है और ओपनजीएल पिक्सेल बफर स्वीकार करेगा। दोनों के बीच कोई विशिष्ट लिंक नहीं है।

बिना तैयारी किए हुए कोडिंग, प्रक्रिया की तरह कुछ होगा:

UIView *view = ... something ...; 

// make space for an RGBA image of the view 
GLubyte *pixelBuffer = (GLubyte *)malloc(
           4 * 
           view.bounds.size.width * 
           view.bounds.size.height); 

// create a suitable CoreGraphics context 
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef context = 
    CGBitmapContextCreate(pixelBuffer, 
          view.bounds.size.width, view.bounds.size.height, 
          8, 4*view.bounds.size.width, 
          colourSpace, 
          kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
CGColorSpaceRelease(colourSpace); 

// draw the view to the buffer 
[view.layer renderInContext:context]; 

// upload to OpenGL 
glTexImage2D(GL_TEXTURE_2D, 0, 
      GL_RGBA, 
      view.bounds.size.width, view.bounds.size.height, 0, 
      GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer); 

// clean up 
CGContextRelease(context); 
free(pixelBuffer); 

कि गैर बिजली के- दो बनावट के बिना हार्डवेयर पर गैर बिजली के- दो दृश्य आकार आसपास के मुद्दों से निपटने नहीं है विस्तार और मान लें कि एक उपयुक्त जीएल बनावट नाम पहले से ही उत्पन्न और बाध्य हो चुका है। अपने लिए जांचें, लेकिन मुझे लगता है कि गैर-शक्ति-दो को एसजीएक्स हार्डवेयर (यानी, आईफोन 3 जीएस के बाद, आईपैड और 8 जीबी तीसरी पीढ़ी के आइपॉड टच के अलावा सभी पर समर्थित है) लेकिन एमबीएक्स पर नहीं।

गैर-शक्ति-दो-बनावटों से निपटने का सबसे आसान तरीका शायद दो बनावट की एक बड़ी पर्याप्त शक्ति बनाने और glTexSubImage2D का उपयोग करने के लिए अपने स्रोत UIView से केवल भाग को अपलोड करने के लिए है।

+0

CVOpenGLESTexture का उपयोग कर CacheCreateTextureForImage सीधे glTexImage2D का उपयोग करने से अधिक कुशल होना चाहिए। पिक्सेल बफर में 'IOSurfaceProperties' और 'OpenGLESCompatibility' कुंजी परिभाषित होनी चाहिए। – OrangeDog

5

एक ओपनजीएल परत को पकड़ने का एक और तरीका है, जो glReadPixels का उपयोग करना है। यह आपकी ओपनजीएल परत के साथ-साथ (मूल रूप से, आपकी दृश्यमान स्क्रीन) के दृश्यमान परतों को भी पकड़ लेगा। इस प्रश्न को देखें: How do I grab an image form my EAGLLayer ?

एक बार जब आपकी छवि हो, तो इसे दो की शक्ति में बदल दिया जाना चाहिए। आप छवि को आज़माकर खींच सकते हैं, लेकिन जब आप इसे फिर से कम करते हैं, या यदि आप इसे बार-बार करते हैं तो गुणवत्ता के मुद्दों का कारण बन जाएगा। बफर बनाने के लिए अतिरिक्त पिक्सल के साथ बेस-2 बनावट में आपकी छवि सामान्य आकार को खींचने का सबसे अच्छा तरीका है।

-(UIImage*)base2Image:(UIImage *) srcImg { 
    int frame2Base = 512; 

    CGSize srcSize = [srcImg size]; 
    CGRect rec = CGRectMake(0, 0, frame2Base, frame2Base); 

    [srcImg drawInRect:rec blendMode:kCGBlendModeNormal alpha:1.0]; 

    //create a context to do our clipping in 
    UIGraphicsBeginImageContext(CGSizeMake(frame2Base, frame2Base)); 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

    //create a rect with the size we want to crop the image to 
    CGRect clippedRect = CGRectMake(0, 0, frame2Base, frame2Base); 
    CGContextClipToRect(currentContext, clippedRect); 

    //create a rect equivalent to the full size of the image 
    CGRect drawRect = CGRectMake(0, 0, srcSize.width, srcSize.height); 

    //draw the image to our clipped context using our offset rect 
    CGContextDrawImage(currentContext, drawRect, srcImg.CGImage); 

    UIImage *dstImg = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return dstImg; 
} 
: यहाँ कोड (मैं किसी और के कोड से संशोधित, लेकिन मैं मूल कोड नहीं मिल रहा है, इसलिए यदि किसी को मूल कोड को देखता है, मुझे पता है, जहां यह श्रेय देना से आया है तो कृपया) है

अब, एक बार ऐसा करने के बाद आप अपनी छवि से सही आकार वाले अनुभाग को खींचने के लिए एक बनावट समन्वय सरणी का उपयोग करें। इस प्रकार:

GLfloat texCoords[] = { 
    0.0, (float)frameHeight/2BaseHeight, 
    0.0, 0.0, 
    (float)frameWidth/2BaseWidth, (float)frameHeight/2BaseHeight, 
    (float)frameWidth/2BaseWidth, 0.0 
}; 

और वहां आपके पास है। आपकी दृश्यमान स्क्रीन से एक स्क्रीनशॉट जो अब एक बनावट है।

+0

यह एक महान तकनीक है! मुझे वास्तव में केवल मेरे दृश्य पदानुक्रम के एक हिस्से की सामग्री प्राप्त करने की आवश्यकता है, लेकिन फिर भी, +1। –

संबंधित मुद्दे