2009-12-30 13 views
10

मैं कई कोर एनीमेशन CALayer ऑब्जेक्ट्स होस्ट करने के लिए NSView का उपयोग कर रहा हूं। मैं जो करने में सक्षम होना चाहता हूं वह दृश्य की वर्तमान स्थिति का एक स्नैपशॉट बिटमैप छवि के रूप में लेना है।मैं एक दृश्य प्रस्तुत कैसे करूं जिसमें कोर एनीमेशन परतों को बिटमैप में शामिल किया गया हो?

यह एक सामान्य NSView कुछ इस तरह का उपयोग कर के साथ अपेक्षाकृत सरल है:

void ClearBitmapImageRep(NSBitmapImageRep* bitmap) { 
    unsigned char* bitmapData = [bitmap bitmapData]; 
    if (bitmapData != NULL) 
     bzero(bitmapData, [bitmap bytesPerRow] * [bitmap pixelsHigh]); 
} 

@implementation NSView (Additions) 
- (NSBitmapImageRep*)bitmapImageRepInRect:(NSRect)rect 
{ 
    NSBitmapImageRep* imageRep = [self bitmapImageRepForCachingDisplayInRect:rect]; 
    ClearBitmapImageRep(imageRep); 
    [self cacheDisplayInRect:rect toBitmapImageRep:imageRep]; 
    return imageRep; 
} 
@end 

हालांकि, जब मैं इस कोड का उपयोग, कोर एनिमेशन परतों गाया नहीं कर रहे हैं।

मैंने CARenderer की जांच की है, जैसा कि मुझे लगता है कि ऐसा करने के लिए प्रतीत होता है, हालांकि मैं इसे अपने मौजूदा परत पेड़ को प्रस्तुत नहीं कर सकता।

NSOpenGLPixelFormatAttribute att[] = 
{ 
    NSOpenGLPFAWindow, 
    NSOpenGLPFADoubleBuffer, 
    NSOpenGLPFAColorSize, 24, 
    NSOpenGLPFAAlphaSize, 8, 
    NSOpenGLPFADepthSize, 24, 
    NSOpenGLPFANoRecovery, 
    NSOpenGLPFAAccelerated, 
    0 
}; 

NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:att]; 
NSOpenGLView* openGLView = [[NSOpenGLView alloc] initWithFrame:[self frame] pixelFormat:pixelFormat]; 
NSOpenGLContext* oglctx = [openGLView openGLContext]; 

CARenderer* renderer = [CARenderer rendererWithCGLContext:[oglctx CGLContextObj] options:nil]; 
renderer.layer = myContentLayer; 
[renderer render]; 
NSBitmapImageRep* bitmap = [oglView bitmapImageRepInRect:[oglView bounds]]; 

हालांकि, जब मैं यह कर मैं एक अपवाद मिलती है:: मैं निम्नलिखित की कोशिश की

CAContextInvalidLayer -- layer <CALayer: 0x1092ea0> is already attached to a context

मेरा अनुमान है कि क्योंकि परत पेड़ मेरी NSView में की मेजबानी की और जाता है कि इस होना चाहिए इसलिए इसके संदर्भ से जुड़ा हुआ है। मुझे समझ में नहीं आता कि मैं NSView से परत पेड़ को बिटमैप में प्रस्तुत करने के लिए कैसे अलग कर सकता हूं, और डुप्लिकेट परत पेड़ बनाने के लिए इस मामले में यह गैर-तुच्छ है।

क्या बिटमैप को प्रस्तुत करने के लिए CALayer s प्राप्त करने का कोई अन्य तरीका है? मुझे ऐसा करने के लिए कहीं भी कोई नमूना कोड नहीं मिल रहा है, वास्तव में मुझे CARenderer के लिए कोई नमूना कोड नहीं मिल रहा है।

उत्तर

15

कोर एनिमेशन रिकॉर्ड करने के बारे में "कोको मेरी प्रेमिका" पर एक शानदार पोस्ट है। लेखक पूरी एनीमेशन को मूवी में कैप्चर करता है, लेकिन आप उस हिस्से का उपयोग कर सकते हैं जहां वह एक ही फ्रेम पकड़ लेता है। इस लेख में "वर्तमान फ्रेम प्राप्त" अनुभाग पर
कूद:
http://www.cimgf.com/2009/02/03/record-your-core-animation-animation/

मूल विचार है:

  • एक CGContext
  • उपयोग CALayer'srenderInContext:
  • बनाएँ NSBitmapImageRep से बनाएं संदर्भ ( का उपयोग कर CGBitmapContextCreateImage और NSBitmapImageRep की initWithCGImage)

अद्यतन:
मैं सिर्फ इतना है कि renderInContext: विधि Mac OS X 10.5 में परतों की सभी प्रकार का समर्थन नहीं करता, पढ़ें। यह निम्नलिखित परतों वर्गों के लिए काम नहीं करता:

  • QCCompositionLayer
  • CAOpenGLLayer
  • QTMovieLayer
+0

बहुत धन्यवाद, यह वही है जो मुझे चाहिए और पूरी तरह से काम करता है। काश मैं '-renderInContext:' विधि पहले देखा था, 'कैरेंडरर' ने मुझे बगीचे के पथ का नेतृत्व किया। –

+0

क्या यह तत्व तत्वों के लिए ऑफस्क्रीन हैं? जैसे मेरे कैलियर में कुछ तत्व हैं जो अभी तक दृश्य फ्रेम में नहीं हैं, लेकिन मुझे उन्हें देखने के लिए स्क्रॉल करने की आवश्यकता है। – Tudorizer

+0

क्या किसी ने इसे एनीमेशन के साथ काम करने के लिए प्राप्त किया है [UIView animateWithDuration: ...]? यह मेरे लिए सही नहीं रहा। – Isak

4

आप कैसे एक NSImage करने के लिए एक CALayer पदानुक्रम रेंडर करने के लिए के लिए नमूना कोड चाहते हैं (या UIImage हैं आईफोन के लिए), आप Core Plot फ्रेमवर्क के सीपीलेयर और इसके -imageOfLayer method देख सकते हैं।हमने वास्तव में एक प्रतिपादन मार्ग बनाया जो सामान्य -रेन्डइन कॉन्टेक्स्ट से स्वतंत्र है: कैलियर द्वारा उपयोग की जाने वाली प्रक्रिया, क्योंकि परतों के पीडीएफ प्रस्तुतिकरण उत्पन्न करते समय सामान्य तरीका वेक्टर तत्वों को संरक्षित नहीं करता है। यही कारण है कि आप इस कोड में -recursivelyRenderInContext: विधि देखेंगे।

हालांकि, यदि आप Weichsel (QCCompositionLayer, CAOpenGLLayer, या QTMovieLayer) द्वारा वर्णित किसी भी प्रकार के परतों से कैप्चर करने का प्रयास कर रहे हैं, तो यह आपकी सहायता नहीं करेगा।

+0

इसके लिए धन्यवाद, यह Weichsel के जवाब से कहीं अधिक व्यापक है, लेकिन वास्तव में मुझे इस मामले में इसकी आवश्यकता है। '-recursivelyRenderInContext:' कोड वास्तव में बहुत अच्छा है। –