iPhone 画像 座標

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
記事: 58
登録日時: 13年前
住所: 大阪府

iPhone 画像 座標

#1

投稿記事 by » 13年前

こんにちは。今回はObjective-Cで画像を好きな位置に表示したいと思って投稿させていただきました。
UIImageViewの位置を直接変えるのではなく、画像自体の座標を指定したいのです。
そこで調べてみると、drawAtPointを使うことが分かりました。
そのあといろいろと試してみたのですが、思った通りに行きませんでした。

コード:

	UIImage *img = [UIImage imageNamed:@"xxxx.png"];
	[img drawAtPoint:CGPointMake(10, 10)];
としてみたのですが、drawAtPointの描画対象も分からず、
このあとどうすればいいのか分かりません。


どなたか教えてくださる方、いらっしゃいましたら
よろしくお願いします。

めるぽん

Re: iPhone 画像 座標

#2

投稿記事 by めるぽん » 13年前

ビューに対しての描画をカスタマイズする場合、普通は UIView の 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
> drawAtPointの描画対象も分からず、
UIImage の drawAtPoint の描画先は、カレントのコンテキストになります。
コンテキストというのが分からなければ、とりあえずはコンテキスト=描画先の画像、と考えればいいです。
普段はカレントのコンテキストは設定されていないのですが、drawRect: 内では UIView のコンテキストがカレントに設定されているため、この中で描画すれば反映されます。

カレントコンテキストを取得したり戻したりといった操作は主に NSGraphicsContext を使います。
ただまあ、自分で作ったビットマップ画像に対して描画したいとかそういうことを行うのであれば使うかもしれませんが、drawRect: 内であれば↑に書いた通り勝手にカレントコンテキストが設定されているので、使うことは無いと思います。

めるぽん

Re: iPhone 画像 座標

#3

投稿記事 by めるぽん » 13年前

もう解決されているかもしれませんが、以前立てられていた左右反転のトピック( http://dixq.net/forum/viewtopic.php?f=3&t=8080
)への回答です(閉鎖中ってなってたのでこっちへ返信します)

ピクセルレベルで反転させるのであれば、仰っているように NSBitmapImageRep を使って うのが一番高レイヤな方法だと思います。
もう少しレイヤを下げれば CGBitmapContextCreate でイメージを作って直接メモリを操作したりといったこともできますね。
ただ、これは反転処理を書くのが手間な上に、手動でピクセルを操作するのは果てしなく遅いのであまりおすすめはできませんが。

ピクセルレベルで反転させなくても、とにかく見た目が反転されてればいいということであれば、描画時に行列を使って反転させるという方法もあります。
UIView の transform に CGAffineTransformScaleCTM(-1.0, 1.0) を設定すれば、UIView が左右反転されて表示されます。
今回みたいに drawRect 内で UIImage を描画するときは、描画する前に CGContextScaleCTM あたりを適用すれば良さそうです。

めるぽん

Re: iPhone 画像 座標

#4

投稿記事 by めるぽん » 13年前

めるぽん さんが書きました:カレントコンテキストを取得したり戻したりといった操作は主に NSGraphicsContext
間違いです。iPhone にはこのクラスは無いようなので、UIGraphicsGetCurrentContext や UIGraphicsPushContext を使って下さい。

アバター
記事: 58
登録日時: 13年前
住所: 大阪府

Re: iPhone 画像 座標

#5

投稿記事 by » 13年前

返信ありがとうございます。
まさか前のトピにも返信いただけるとは!

どちらもやってみますね。

アバター
記事: 58
登録日時: 13年前
住所: 大阪府

Re: iPhone 画像 座標

#6

投稿記事 by » 13年前

描画カスタマイズの方ですが、とりあえずコンパイルは通りました。
しかし何も表示されないままです(T_T)
どこが間違っているのでしょう?

現在のコードです。
[UntitledViewController.h]

コード:

#import <UIKit/UIKit.h>

@interface UntitledViewController : UIViewController {
}
@end

@interface HogeView : UIView {
}
@end
[UntitledViewController.m]

コード:

#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 画像 座標

#7

投稿記事 by めるぽん » 13年前

UntitledViewController の view に、作った HogeView をちゃんと追加してやらないとダメですね。

コード:

- (void)viewDidLoad {
    [super viewDidLoad];
    HogeView *view = [[[HogeView alloc] initWithFrame:self.view.bounds] autorelease];
    [self.view addSubview:view];
}

めるぽん

Re: iPhone 画像 座標

#8

投稿記事 by めるぽん » 13年前

black_cat さんが書きました:
めるぽん さんが書きました:drawRect: 内では UIView のコンテキストがカレントに設定されている
とはどういうことでしょう?
UIImageViewのようなものは必要ないということでしょうか?
Windows プログラミングをしたことがあるならデバイスコンテキストというのを聞いたことがあると思いますが、ここで言っているコンテキストはまさにそれのことです。
まあ単純に、drawRect: 内なら drawAtPoint 等でそのビューに画像を表示できる、と覚えておけばいいと思います。

もう少し詳細に説明すると、実際のところは、UIView の drawRect: を呼んでいる周りのコードはこんな感じになっています。

コード:

CGContextRef context = ...; // UIView へのコンテキストを取得
UIGraphicsPushContext(context); // このコンテキストをカレントに設定
[self drawRect:rect]; // ここでの描画は、context に反映される。つまり UIView が更新される
UIGraphicsPopContext(context);
この CGContextRef というのが、Windows で言うところの HDC と同じような役割を果たします。
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)];
}
多分こんな感じになると思います(実際に動かした訳じゃないので間違ってるかもですが)。

アバター
記事: 58
登録日時: 13年前
住所: 大阪府

Re: iPhone 画像 座標

#9

投稿記事 by » 13年前

とても詳しく教えてくださって本当にありがとうございました。
無事に(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
とすると、(0, 0)に描画されてしまいます。

どうすれば引数で指定した位置に描画出来ますか?

めるぽん

Re: iPhone 画像 座標

#10

投稿記事 by めるぽん » 13年前

black_cat さんが書きました: drawRect: を呼び出すときには
[view drawRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f)];
としているのに、
drawRect: は、再描画が必要になったときに「システムが」 呼び出すもので、自分で直接呼び出すものではないです。
自分で指定した場所に描画したい場合は、メンバに持たせるなりして下さい。

あと再描画が必要な場合も drawRect: を直接呼び出してはいけないです。そういう場合には setNeedsDisplay を使って下さい。
setNeedsDisplay はシステムへ再描画を要求する命令で、そうすると、どこかのタイミングでシステムが drawRect: を呼び出してくれます。

アバター
記事: 58
登録日時: 13年前
住所: 大阪府

Re: iPhone 画像 座標

#11

投稿記事 by » 13年前

ありがとうございます^^
これで納得です!
めるぽん さんが書きました:そういう場合には setNeedsDisplay を使って下さい
できましたよ! b


左右反転の方はまだ試していませんが、これから頑張っていこうと思います!
いろいろと詳しく教えていただいて、ありがとうございました。

アバター
記事: 58
登録日時: 13年前
住所: 大阪府

Re: iPhone 画像 座標

#12

投稿記事 by » 13年前

反転の方もできました!

「CGAffineTransformScaleCTM」は調べてもhitしなかったので、
CGAffineTransformScaleを使ってみると見事に反転できました!

コード:

	CGAffineTransform tf = xx.transform;
	//反転する
	tf = CGAffineTransformScale(tf, -1.0f, 1.0f);
    xx.transform = tf;
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る