سؤال

أحاول استخدام ميزة SELECT ونسخ من IKIMAGEVIEW. إذا كان كل ما تريد القيام به هو وجود تطبيق يحتوي على صورة ، فحدد جزءًا ونسخه إلى الحافظة ، فهذا أمر سهل. قمت بتعيين قائمة النسخ اختيار على طريقة المستجيب الأول: (ID) وأسلوب كل شيء بطريقة سحرية.

ومع ذلك ، إذا كنت تريد شيئًا أكثر تعقيدًا ، مثلما تريد نسخه كجزء من بعض العمليات الأخرى ، لا يبدو لي أن أجد الطريقة للقيام بذلك.

لا يبدو أن IkimageView لديه طريقة نسخ ، ولا يبدو أن لديها طريقة تخبرك بالمستطيل المحدد!

لقد مررت بكتاب Hillegass ، لذلك أفهم كيف تعمل الحافظة ، وليس فقط كيفية إخراج جزء من الصورة من العرض ...

الآن ، بدأت أعتقد أنني ارتكبت خطأً في وضع مشروعي على IkimageView ، ولكن هذا ما تم بناء المعاينة (أو هكذا قرأت) ، لذلك اعتقدت أنه يجب أن يكون مستقرًا ... وعلى أي حال ، الآن فات الأوان ، أنا عميق جدًا في هذا الأمر ...

لذلك ، بخلاف عدم استخدام IkimageView ، أي اقتراحات حول كيفية نسخ المنطقة المحددة إلى الحافظة يدويًا؟

تعديل في الواقع ، لقد وجدت طريقة النسخة (معرف) ، لكن عندما أسميها ، أحصل عليها

 <Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 2624 bytes/row.

من الواضح أن هذا لا يحدث عندما أقوم بنسخة عادية من خلال المستجيب الأول ... أفهم رسالة الخطأ ، لكنني لست متأكدًا من أين تحصل على هذه المعلمات من ...

هل هناك أي طريقة لتتبع هذا ومعرفة كيف يحدث هذا؟ لن يساعد تصحيح الأخطاء لأسباب واضحة ، وكذلك حقيقة أنني أقوم بذلك في موزيلا ، لذلك فإن تصحيح الأخطاء ليس خيارًا على أي حال ...

تحرير 2 يحدث لي أن الطريقة: (المعرف) الذي وجدته قد تقوم بنسخ العرض بدلاً من نسخ جزء من الصورة إلى الحافظة ، وهو ما أحتاجه.

السبب في أنني اعتقدت أن نسخة الحافظة هي أنه في مشروع آخر ، حيث أقوم بالنسخ من ikimageview إلى الحافظة مباشرة من قائمة التحرير ، فإنه يرسل نسخة: (معرف) إلى FirstreSponder ، لكنني لست في الواقع تأكد من ما يفعله FirstreSponder معها ...

تحرير 3 يبدو أن خطأ CGBITMAPContextCreate يأتي من [imageView image] الذي ، بشكل غريب بما فيه الكفاية ، هو طريقة موثقة.

من الممكن أن يحدث هذا لأنني أضع الصورة هناك باستخدام طريقة setImage: (معرف) ، وتمريرها nsimage*... هل هناك طريقة أخرى أكثر ذكاءً للحصول على nsimage في مقابلة IkimageView؟

هل كانت مفيدة؟

المحلول

ال -copy: الطريقة في IKImageView يفعل ما كل شيء آخر -copy: الطريقة لا: ينسخ التحديد الحالي إلى الحافظة. ومع ذلك ، يتم تنفيذها كطريقة خاصة في IKImageView لسبب ما.

يمكنك فقط تسميته مباشرة:

[imageView copy:nil];

سيؤدي ذلك إلى نسخ كل ما يتم اختياره حاليًا إلى الحافظة.

لا أعتقد أن هناك طريقة للوصول مباشرة إلى محتوى الصورة في التحديد الحالي في IKImageView باستخدام الأساليب العامة ، يعد هذا مرشحًا جيدًا لتقرير الأخطاء/طلب الميزة.

ومع ذلك ، يمكنك استخدام الطريقة الخاصة -selectionRect للحصول على CGRect من التحديد الحالي واستخدام ذلك لاستخراج الجزء المحدد من الصورة:

//stop the compiler from complaining when we call a private method
@interface IKImageView (CompilerSTFU)
- (CGRect)selectionRect
@end

@implementation YourController
//imageView is an IBOutlet connected to your IKImageView
- (NSImage*)selectedImage
{
    //get the current selection
    CGRect selection = [imageView selectionRect];

    //get the portion of the image that the selection defines
    CGImageRef selectedImage = CGImageCreateWithImageInRect([imageView image],(CGRect)selection);

    //convert it to an NSBitmapImageRep
    NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:selectedImage] autorelease];
    CGImageRelease(selectedImage);

    //create an image from the bitmap data
    NSImage* image = [[[NSImage alloc] initWithData:[bitmap TIFFRepresentation]] autorelease];

    //in 10.6 you can skip converting to an NSBitmapImageRep by doing this:
    //NSImage* image = [[NSImage alloc] initWithCGImage:selectedImage size:NSZeroSize];     
    return image;
}
@end

نصائح أخرى

حسنًا ، لذا فإن النسخة: NIL تفشل ، وفشل [ImageView Image] ، ولكن اتضح أن لدي نسخة أخرى من nsimage من عندما أضفتها إلى العرض في المقام الأول ، لذلك يمكنني ذلك. أيضا ، يتوقع cgimagecreatewithimageinrect cgimageref وليس nsimage*، لذلك كان علي القيام ببعض التحويلات.

بالإضافة إلى ذلك ، لسبب ما يتم قلب مستطيل التحديد ، إما أن يكون أسفله ، والصورة من أعلى ، أو العكس ، لذلك اضطررت إلى قلبه.

ولسبب ما ، بدأ التحويل البرمجي فجأة يشكو من أن NSRECT ليس بنفس نوع CGRECT (مما يعني أنه ذهب فجأة من 32 إلى 64 بت أو شيء من هذا القبيل ... غير متأكد من السبب ...)

على أي حال ، إليك نسختي من SelectImage:

- (NSImage*)selectedImage
{
    //get the current selection
    CGRect selection = flipCGRect(imageView, [imageView selectionRect]);

    //get the portion of the image that the selection defines
    struct CGImage * full = [[doc currentImage] CGImageForProposedRect: NULL context: NULL hints: NULL];

    CGImageRef selectedImage = CGImageCreateWithImageInRect( full, selection);


    //convert it to an NSBitmapImageRep
    NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:selectedImage] autorelease];
    CGImageRelease(selectedImage);

//     //create an image from the bitmap data
    NSImage* image = [[[NSImage alloc] initWithData:[bitmap TIFFRepresentation]] autorelease];

//     //in 10.6 you can skip converting to an NSBitmapImageRep by doing this:
    //NSImage* image = [[NSImage alloc] initWithCGImage:selectedImage size:NSZeroSize];     
    return image;

}

كتبت FlipcGrect ، و [Doc currentimage] يعيد nsimage*...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top