iPhone 画像 座標
iPhone 画像 座標
こんにちは。今回はObjective-Cで画像を好きな位置に表示したいと思って投稿させていただきました。
UIImageViewの位置を直接変えるのではなく、画像自体の座標を指定したいのです。
そこで調べてみると、drawAtPointを使うことが分かりました。
そのあといろいろと試してみたのですが、思った通りに行きませんでした。
としてみたのですが、drawAtPointの描画対象も分からず、
このあとどうすればいいのか分かりません。
どなたか教えてくださる方、いらっしゃいましたら
よろしくお願いします。
UIImageViewの位置を直接変えるのではなく、画像自体の座標を指定したいのです。
そこで調べてみると、drawAtPointを使うことが分かりました。
そのあといろいろと試してみたのですが、思った通りに行きませんでした。
としてみたのですが、drawAtPointの描画対象も分からず、
このあとどうすればいいのか分かりません。
どなたか教えてくださる方、いらっしゃいましたら
よろしくお願いします。
Re: iPhone 画像 座標
ビューに対しての描画をカスタマイズする場合、普通は UIView の drawRect: メソッドをオーバーライドして行います。
> drawAtPointの描画対象も分からず、
UIImage の drawAtPoint の描画先は、カレントのコンテキストになります。
コンテキストというのが分からなければ、とりあえずはコンテキスト=描画先の画像、と考えればいいです。
普段はカレントのコンテキストは設定されていないのですが、drawRect: 内では UIView のコンテキストがカレントに設定されているため、この中で描画すれば反映されます。
カレントコンテキストを取得したり戻したりといった操作は主に NSGraphicsContext を使います。
ただまあ、自分で作ったビットマップ画像に対して描画したいとかそういうことを行うのであれば使うかもしれませんが、drawRect: 内であれば↑に書いた通り勝手にカレントコンテキストが設定されているので、使うことは無いと思います。
@interface HogeView : UIView {
}
@end
@implementation HogeView
- (void)drawRect:(CGRect)rect {
// [super drawRect:rect] // 必要であれば呼び出してやる
UIImage *img = [UIImage imageNamed:@"xxxx.png"];
[img drawAtPoint:CGPointMake(10, 10)];
}
@end
UIImage の drawAtPoint の描画先は、カレントのコンテキストになります。
コンテキストというのが分からなければ、とりあえずはコンテキスト=描画先の画像、と考えればいいです。
普段はカレントのコンテキストは設定されていないのですが、drawRect: 内では UIView のコンテキストがカレントに設定されているため、この中で描画すれば反映されます。
カレントコンテキストを取得したり戻したりといった操作は主に NSGraphicsContext を使います。
ただまあ、自分で作ったビットマップ画像に対して描画したいとかそういうことを行うのであれば使うかもしれませんが、drawRect: 内であれば↑に書いた通り勝手にカレントコンテキストが設定されているので、使うことは無いと思います。
Re: iPhone 画像 座標
もう解決されているかもしれませんが、以前立てられていた左右反転のトピック( http://dixq.net/forum/viewtopic.php?f=3&t=8080
)への回答です(閉鎖中ってなってたのでこっちへ返信します)
ピクセルレベルで反転させるのであれば、仰っているように NSBitmapImageRep を使って うのが一番高レイヤな方法だと思います。
もう少しレイヤを下げれば CGBitmapContextCreate でイメージを作って直接メモリを操作したりといったこともできますね。
ただ、これは反転処理を書くのが手間な上に、手動でピクセルを操作するのは果てしなく遅いのであまりおすすめはできませんが。
ピクセルレベルで反転させなくても、とにかく見た目が反転されてればいいということであれば、描画時に行列を使って反転させるという方法もあります。
UIView の transform に CGAffineTransformScaleCTM(-1.0, 1.0) を設定すれば、UIView が左右反転されて表示されます。
今回みたいに drawRect 内で UIImage を描画するときは、描画する前に CGContextScaleCTM あたりを適用すれば良さそうです。
)への回答です(閉鎖中ってなってたのでこっちへ返信します)
ピクセルレベルで反転させるのであれば、仰っているように NSBitmapImageRep を使って うのが一番高レイヤな方法だと思います。
もう少しレイヤを下げれば CGBitmapContextCreate でイメージを作って直接メモリを操作したりといったこともできますね。
ただ、これは反転処理を書くのが手間な上に、手動でピクセルを操作するのは果てしなく遅いのであまりおすすめはできませんが。
ピクセルレベルで反転させなくても、とにかく見た目が反転されてればいいということであれば、描画時に行列を使って反転させるという方法もあります。
UIView の transform に CGAffineTransformScaleCTM(-1.0, 1.0) を設定すれば、UIView が左右反転されて表示されます。
今回みたいに drawRect 内で UIImage を描画するときは、描画する前に CGContextScaleCTM あたりを適用すれば良さそうです。
Re: iPhone 画像 座標
間違いです。iPhone にはこのクラスは無いようなので、UIGraphicsGetCurrentContext や UIGraphicsPushContext を使って下さい。めるぽん さんが書きました:カレントコンテキストを取得したり戻したりといった操作は主に NSGraphicsContext
Re: iPhone 画像 座標
描画カスタマイズの方ですが、とりあえずコンパイルは通りました。
しかし何も表示されないままです(T_T)
どこが間違っているのでしょう?
現在のコードです。
[UntitledViewController.h]
[UntitledViewController.m]
あと、
UIImageViewのようなものは必要ないということでしょうか?
初心者なんで馬鹿なことをお聞きしていたらすみません。
しかし何も表示されないままです(T_T)
どこが間違っているのでしょう?
現在のコードです。
[UntitledViewController.h]
#import <UIKit/UIKit.h>
@interface UntitledViewController : UIViewController {
}
@end
@interface HogeView : UIView {
}
@end
#import "UntitledViewController.h"
@implementation UntitledViewController
- (void)viewDidLoad {
[super viewDidLoad];
HogeView *view = [[HogeView alloc] init];
[view drawRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f)];
}
@end
@implementation HogeView
- (void)drawRect:(CGRect)rect {
// [super drawRect:rect]; // 必要であれば呼び出してやる
UIImage *img = [UIImage imageNamed:@"xxxx.png"];
[img drawAtPoint:CGPointMake(10, 10)];
}
@end
あと、
とはどういうことでしょう?めるぽん さんが書きました:drawRect: 内では UIView のコンテキストがカレントに設定されている
UIImageViewのようなものは必要ないということでしょうか?
初心者なんで馬鹿なことをお聞きしていたらすみません。
Re: iPhone 画像 座標
Windows プログラミングをしたことがあるならデバイスコンテキストというのを聞いたことがあると思いますが、ここで言っているコンテキストはまさにそれのことです。black_cat さんが書きました:とはどういうことでしょう?めるぽん さんが書きました:drawRect: 内では UIView のコンテキストがカレントに設定されている
UIImageViewのようなものは必要ないということでしょうか?
まあ単純に、drawRect: 内なら drawAtPoint 等でそのビューに画像を表示できる、と覚えておけばいいと思います。
もう少し詳細に説明すると、実際のところは、UIView の drawRect: を呼んでいる周りのコードはこんな感じになっています。
CGContextRef context = ...; // UIView へのコンテキストを取得
UIGraphicsPushContext(context); // このコンテキストをカレントに設定
[self drawRect:rect]; // ここでの描画は、context に反映される。つまり UIView が更新される
UIGraphicsPopContext(context);
Windows において、WM_PAINT で HDC を BeginPaint して、それを使って描画していたと思いますが、これも同じようなものですね。Windows では明示的に引数に HDC を渡していたものが、iPhone では UIGraphicsPushContext で事前に設定されるようになっただけです。
どうしても drawRect: の外で描画したいと思うのであれば、オフスクリーンを作るという手もあります。
- (id)init {
if (self = [super init]) {
// 新しいイメージを作って CGContextRef を取得
context = CGBitmapContextCreate(/* 適当にごちゃごちゃした引数を渡してオフスクリーンを作る */);
// このコンテキストから CGImageRef を取り出して UIImage を作成
CGImageRef image = CGBitmapContextCreateImage(context);
contextImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
}
}
- (void)dealloc {
[contextImage release];
CGContextRelease(context);
}
// なんかの処理
- (void)doSomething {
UIGraphicsPushContext(context);
// image をオフスクリーンに描画
UIImage* image = [UIImage imageNamed:@"xxx.png"];
[image drawAtPoint:CGPointMake(10, 10)];
UIGraphicsPopContext(context);
// 必要であればビューの再描画を依頼する
// [self setNeedsDisplay];
}
// オフスクリーンをビューに描画
- (void)drawRect:(CGRect)rect {
[contextImage drawAtPoint:CGPointMake(0,0)];
}
Re: iPhone 画像 座標
とても詳しく教えてくださって本当にありがとうございました。
無事に(10, 10)の位置に描画できました!
しかしあと1箇所だけ納得のいかないところがあります。
drawRect: を呼び出すときには
[view drawRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f)];
としているのに、
とすると、(0, 0)に描画されてしまいます。
どうすれば引数で指定した位置に描画出来ますか?
無事に(10, 10)の位置に描画できました!
しかしあと1箇所だけ納得のいかないところがあります。
drawRect: を呼び出すときには
[view drawRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f)];
としているのに、
@implementation HogeView
- (void)drawRect:(CGRect)rect {
//[super drawRect:rect]; // 必要であれば呼び出してやる
UIImage *img = [UIImage imageNamed:@"xxxx.png"];
[img drawAtPoint:CGPointMake(rect.origin.x, rect.origin.y)]; //←ここだけ変えました。
}
@end
どうすれば引数で指定した位置に描画出来ますか?
Re: iPhone 画像 座標
drawRect: は、再描画が必要になったときに「システムが」 呼び出すもので、自分で直接呼び出すものではないです。black_cat さんが書きました: drawRect: を呼び出すときには
[view drawRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f)];
としているのに、
自分で指定した場所に描画したい場合は、メンバに持たせるなりして下さい。
あと再描画が必要な場合も drawRect: を直接呼び出してはいけないです。そういう場合には setNeedsDisplay を使って下さい。
setNeedsDisplay はシステムへ再描画を要求する命令で、そうすると、どこかのタイミングでシステムが drawRect: を呼び出してくれます。
Re: iPhone 画像 座標
ありがとうございます^^
これで納得です!
左右反転の方はまだ試していませんが、これから頑張っていこうと思います!
いろいろと詳しく教えていただいて、ありがとうございました。
これで納得です!
できましたよ! bめるぽん さんが書きました:そういう場合には setNeedsDisplay を使って下さい
左右反転の方はまだ試していませんが、これから頑張っていこうと思います!
いろいろと詳しく教えていただいて、ありがとうございました。