イメージの扱いで
public ImageTrans(String fileName){
// 親クラスである Frameクラスのコンストラクタを
// タイトル文字列を "ImageTrans"として呼ぶ.
super("ImageTrans");
// 現在の Toolkit を得て,getImageで PNG 形式のファイルを指定して,
// イメージを得る.
// インスタンス変数 fileNameへコンストラクタの引数 fileNameの代入
this.fileName=fileName;
親クラスのコンストラクタを呼んだということは、"ImageTrans"という値を
親クラスのコンストラクタの引数に指定し、親クラスにあったメンバ変数をそ
の引数で初期化したということですよね。どこでfileNameオブジェクトがつく
られたのでしょうか?また、 thisは今扱われているオブジェクトを指している
のに、どこでもオブジェクトは扱われていないと思うのですが?
TAの小田原です。
> 親クラスのコンストラクタを呼んだということは、"ImageTrans"という値
> を親クラスのコンストラクタの引数に指定し、親クラスにあったメンバ変数
> をその引数で初期化したということですよね。
はいその通りです。その結果、この場合ではフレームのタイトルバーに書かれ
る文字列が"ImageTrans"になります。
> どこでfileNameオブジェクトがつくられたのでしょうか?
確認しておくと、fileNameというのはこのクラスが持っているインスタンス変
数です。そこで、
> this.fileName = fileName;
という文でfileNameに値を代入しています。右辺のfileNameは、たまたま左辺
と同じ変数名ですが意味的には全く異なり、
> public ImageTrans(String fileName){
にあるようにコンストラクタの引数を表す変数にすぎません。
このコンストラクタは実際にmainの下の文で呼び出され、
> ImageTrans frame=new ImageTrans(args[0]);
引数は args[0] となっているので、javaを実行するときの引数の文字列が
fileNameとして扱われることになります。
と確認だけで説明が終わってしまいそうですが、質問の答えになっているでしょ
うか…(;;
> また、 thisは今扱われているオブジェクトを指しているのに、どこでもオ
> ブジェクトは扱われていないと思うのですが?
コンストラクタの中でthisという変数が使われている場合、thisはそのコンス
トラクタで生成されるオブジェクトを指していると思って下さい。
ですから、この場合には
> ImageTrans frame=new ImageTrans(args[0]);
で生成されたframeというオブジェクトを指しています。
したがって、this.fileNameというのは、frame.fileNameということだ、と理
解してよいと思います。
イメージから、ピクセルデータの取得で
int w=image.getWidth(ImageTrans.this);
int h=image.getHeight(ImageTrans.this);
はimageオブジェクトにgetWidthやgetHeightメソッドの参照を行い、メソッド
ではImageTrans.thisを使っていると思うのですが、imageはクラス変数(メン
バ変数?インスタンス変数?)であってオブジェクトではないのでは?また
ImageTrans.thisの意味がわかりません。ImageTransクラスの何でしょう?
System.err.println(w+","+h);
errの意味がわかりません。outと同じですか?
System.exit(1)
中身が0のときと何か違うのですか?
printPpmPixel(pixels[j * w + i]
ピクセルの配列は[h * w]ではないのですか?
// ImageTransクラスのインスタンスを作る.ImageTrans frame=new
ImageTrans(args[0]); args[0]が String型のfileName変数に代入されると
いうことですか?このインスタンスを作るために、コンストラクタメソッ
ドで
this.fileName=fileName
として、メンバ変数の値をfileName変数(args[0])によって初期化したのですか?
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel ) & 0xff;
で、0xffとは何ですか?また、たとえばpixel >> 8、では、alphaとredの数も入ってしまうのでは?
このプログラムは、全体として、
1、 メインメソッド>コンストラクタ呼び出し
2、コンストラクタ
3、適宜paintメソッドが呼び出される
という構造ですか?コンストラクタはオブジェクトを作るために、メンバ変数
を初期化するものだと思っていたのですが、ここでは、メソッドのような役割
を果たしているのですか?
> イメージから、ピクセルデータの取得で >int w=image.getWidth(ImageTrans.this); >int h=image.getHeight(ImageTrans.this); >はimageオブジェクトにgetWidthやgetHeightメソッドの参照を行い、メソッド >ではImageTrans.thisを使っていると思うのですが、 「正確にいうと,変数imageの指すImage型のオブジェクトに」ということになります. >imageはクラス変数(メン >バ変数?インスタンス変数?)であってオブジェクトではないのでは?また imageはインスタンス変数です.オブジェクト型の「変数」を「参照」する場合は, ・ 変数の内容が null の場合はNullPointer 例外が発生 ・ 変数があるオブジェクトを指す時は,そのオブジェクトに対して操作 となります. >ImageTrans.thisの意味がわかりません。ImageTransクラスの何でしょう? 良いところに気が付きました.あの部分は 1.ImageTransクラスの中(Inner class)の 2. MouseAdapterのサブクラスの無名クラス のメソッドmousePressedにあたります.ここで,2のインスタンスはthisで得ら れますが,1のインスタンスを得るための記法として,ImageTrans.thisという 書き方があります.この部分は説明が必要でしたね. >System.err.println(w+","+h); >errの意味がわかりません。outと同じですか? これはUnixの文化ですが,プログラムの出力として標準出力と標準エラー出力 の2種類が用意されています.他のプログラムで処理をするためにファイル等に 出力したい場合などは,標準出力に,本来の出力ではなく,単にメッセージを 出したい場合は標準エラー出力に出します.この部分は途中経過を表示するだ けが目的で,標準出力には生成される画像ファイル(PPMファイル)を出力したい ので標準エラー出力に出しています. >System.exit(1) >中身が0のときと何か違うのですか? これも Unix 文化によるもので,あるコマンドがSystem.exit(0)で終了した時 は,正常終了で System.exit(0以外の値)で終了した時は,何らかのエラーで 終了したことを示します.多くのshellでは echo $? で,最後に実行したコマンドの終了ステータスが分かります. > printPpmPixel(pixels[j * w + i] > ピクセルの配列は[h * w]ではないのですか? ピクセルの配列の大きさは h * w あります. jが0からh-1まで,iが0からw-1まで動くので, j * w + i は0から(h-1)*w+(w-1) = h*w-1 まで動きます. > // ImageTransクラスのインスタンスを作る. > ImageTrans frame=new ImageTrans(args[0]); >args[0]が String型のfileName変数に代入されるということですか? args[0]によって指されている String型のオブジェクトがString型の fileNameという引数に代入されるということです. >このイン >スタンスを作るために、コンストラクタメソッドで >this.fileName=fileName >として、メンバ変数の値をfileName変数(args[0])によって初期化したのですか? args[0]によって指されているString型のオブジェクトは,mainが呼ばれる前 に,java処理系によって作られている. > int alpha = (pixel >> 24) & 0xff; > int red = (pixel >> 16) & 0xff; > int green = (pixel >> 8) & 0xff; > int blue = (pixel ) & 0xff; >で、0xffとは何ですか?また、たとえばpixel >> 8、では、alphaとredの数も入ってしまうのでは? 0xffの「0x」は次に続くのが16進数であることを示しています.16進数でfは 15なので,0xffは15*16+15=255となります.0xffと 論理積(&)をとることは, 下位8ビットのみを残して,残りを0でクリアすることを意味します.たとえば, greenを取るには,元のpixel データ +--------+--------+--------+-------+ | alpha | red | green | blue | +--------+--------+--------+-------+ 31 ----24|23----16|15-----8|7-----0 から,pixel>>8で +--------+--------+--------+--------+ |00000000| alpha | red | green | +--------+--------+--------+--------+ 31 ----24|23----16|15-----8|7-----0 としてから,&0xffで +--------+--------+--------+--------+ |00000000|00000000|00000000| green | +--------+--------+--------+--------+ 31 ----24|23----16|15-----8|7-----0 とします. >このプログラムは、全体として、 >1、 メインメソッド>コンストラクタ呼び出し >2、コンストラクタ >3、適宜paintメソッドが呼び出される >という構造ですか? そうです. >コンストラクタはオブジェクトを作るために、メンバ変数 >を初期化するものだと思っていたのですが、ここでは、メソッドのような役割 >を果たしているのですか? コンストラクタはオブジェクトを初期化するためのものですが,オブジェクト の初期化はFrameクラスのオブジェクトのように,入出力ともからむものの場合 は,メンバ変数の初期化以外の操作を伴う場合があります.
ImageTrans,ImageLens プログラムをそのままコンパイルして実行したら、上手 くいきません。どうしてでしょう?
エラーを見てみる必要がありますが,ecc.gifというgif形式のファイルがない ディレクトリで実行したということはありませんか?
ピクセルデータからイメージの作成で
// ImageLensクラスのコンストラクタ
String fileName;
// (x,y)に大きさlensSize(50)のレンズを置いたイメージをshowImageにして,repaintする
void transImage(int x, int y)
ImageLensクラスのコンストラクタなのにどうしてコンストラクタ名が
ImageLensでなく、transImageなのでしょう?
int w=image.getWidth(this);
int h=image.getHeight(this);
thisとは何ですか?
if(pixels==null || pixels.length< w*h)
まだpixels配列は作られていないのだから、pixels==null はわかるのですが、
配列の数なども決まっていなく、pixels.length< w*hの条件の意味がわかりま
せん。
pixels=new int[w * h];
showPixels=new int[w * h];
どうして配列を二つも作っているのですか?
System.arraycopy(pixels,0,showPixels,0,w*h);
for (int j = Math.max(0,y-lensSize); j < Math.min(h,y+lensSize); j++) {
int dy=j-y;
for (int i = Math.max(0,x-lensSize); i < Math.min(w,x+lensSize); i++) {
int dx=i-x;
double r=Math.sqrt((double)(dx*dx+dy*dy)/(double)(lensSize*lensSize));
if(r<1.0){
showPixels[j*w+i]=pixels[(y+(int)(dy*r))*w+(x+(int)(dx*r))];
arraycopyの意味がわかりません。ここは全体として、配列の数だけピクセルを
並べているということですか?
> ピクセルデータからイメージの作成で
> // ImageLensクラスのコンストラクタ
> String fileName;
> // (x,y)に大きさlensSize(50)のレンズを置いたイメージをshowImageにして,repaintする
> void transImage(int x, int y)
> ImageLensクラスのコンストラクタなのにどうしてコンストラクタ名が
> ImageLensでなく、transImageなのでしょう?
失礼,コメントの位置が違っていました transImageはコンストラクタではな
く通常のメソッドです.
> int w=image.getWidth(this);
> int h=image.getHeight(this);
> thisとは何ですか?
クラスImageLensのオブジェクトです.
> if(pixels==null || pixels.length< w*h)
>まだpixels配列は作られていない
> のだから、pixels==null はわかるのですが、配列の数なども決まっていなく、
> pixels.length< w*hの条件の意味がわかりません。
int w=image.getWidth(this);
int h=image.getHeight(this);
で得られる w, h の値はネットワークごしに画像を持って来ている途中などは,
最終的な画像の大きさではなく,途中までロードした部分の画像の大きさが返
ることがあります.そのため,一度 pixelsを確保しても足りなくなる恐れがあ
るので,チェックして以前確保した領域が足りない場合は,もう一度取り直し
ています.
> pixels=new int[w * h];
> showPixels=new int[w * h];
> どうして配列を二つも作っているのですか?
講義でも説明したと思いますが,元のイメージに対応するのが pixelsで,レ
ンズ上に変形させてつくり出した画像がshowPixelsになります.
> System.arraycopy(pixels,0,showPixels,0,w*h);
> arraycopyの意味がわかりません。ここは全体として、配列の数だけピクセル
> を並べているということですか?
順序が逆になってしみましたが,arraycopyの意味は,「Vectorクラス」の中で,
> なお,
> int i;
> for(i=0;i< lines.length;i++)
> newLines[i]=lines[i];
>
>のように,配列から配列へのコピーは,Systemクラスの arraycopyメソッドを
>使って,以下のように書くことができる.
>
> System.arraycopy(lines,0,newLines,0,lines.length);
と説明しています.
Forbidden You don't have permission to access /~ktanaka/programming03/kadai1202.html on this server.とうメッセージが出てアクセ スできないはずである.17:00以降にも同様のエラーが出る時は,Shiftキーを 押しながら,再読み込み(Reload)を押してみること.
課題の締切りは12/16(火)の21時まで