سؤال آخر IkimageView: نسخ منطقة
-
21-09-2019 - |
سؤال
أحاول استخدام ميزة 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*...