IKImageView の別の質問:リージョンをコピーする
-
21-09-2019 - |
質問
IKImageView の選択とコピー機能を使用しようとしています。画像を含むアプリを作りたいだけなら、その一部を選択してクリップボードにコピーするのが簡単です。コピー メニューの選択をファーストレスポンダーの copy:(id) メソッドに設定すると、魔法のようにすべてが機能します。
ただし、他の操作の一部としてコピーするなど、より複雑なことが必要な場合は、これを行う方法が見つからないようです。
IKImageView には copy メソッドがないようです。選択された四角形を通知するメソッドさえもないようです。
私は Hillegass の本を読んだので、クリップボードがどのように機能するかは理解しましたが、画像の一部をビューから外す方法は理解できませんでした...
今、私は自分のプロジェクトを IKImageView に基づいて作成したのが間違いだったのではないかと思い始めていますが、Preview は IKImageView に基づいて構築されている (または私が読んだ) ので、安定している必要があると考えました...とにかく、もう手遅れです、私はこの問題に深く入り込みすぎて、最初からやり直すことはできません...
それでは、IKImageView を使用しない以外に、選択領域を手動でクリップボードにコピーする方法について何か提案はありますか?
編集 実際、copy(id) メソッドを見つけましたが、それを呼び出すと、
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 2624 bytes/row.
ファーストレスポンダを介して通常のコピーを実行した場合、これは明らかに起こりません...エラーメッセージは理解できますが、それらのパラメータをどこから取得しているのかわかりません...
これを追跡して、これがどのように起こっているかを確認する方法はありますか?デバッガは明らかな理由で役に立ちません。また、これを Mozilla で実行しているため、デバッガは選択肢にありません...
編集2 私が見つけた copy:(id) メソッドは、画像のチャンクをクリップボードにコピーするのではなく、VIEW をコピーしている可能性があることに気づきました。これは私が必要としているものです。
これがクリップボードのコピーだと思った理由は、編集メニューから直接 IKImageView からクリップボードにコピーしている別のプロジェクトでは、copy:(id) が firstResponder に送信されるだけですが、そうではないからです。実際のところ、ファーストレスポンダーがそれを使って何をしているかはわかります...
編集3 CGBitmapContextCreate エラーの原因は次のとおりです。 [imageView image]
奇妙なことに、それは は 文書化された方法。
setImage:(id) メソッドを使用してそこに画像を配置し、それに 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
他のヒント
[OK]を、コピーので:nilは失敗し、[ImageViewのイメージ]は失敗したが、それは私がそれをできたので、私は、私が最初の場所でのビューにそれを追加したときから、NSImageではの別のコピーを持っていることが判明しました。また、CGImageCreateWithImageInRectはCGImageRefないNSImageでは*は、私はいくつかの変換をしなければならなかったので、期待しています。
また、何らかの理由で選択矩形はどちらかそれの底がorigined、ひっくり返され、そして私はそれを反転しなければならなかったので画像は、トップ、あるいは他の方法で回避されます。
そして、いくつかの理由のために、コンパイラが突然NSRectが
とにかく、ここでselectedImageの私のコピーは、次のとおりです。
- (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、および[ドキュメントのcurrentImage]を書いて返すNSImageでは* ...