- ベストアンサー
MATLABのGUIDEでフォルダ内の画像ファイルを表示する方法。
MATLABのGUIDEでフォルダ内の画像ファイルを表示する方法。 MATLABのGUIDE内であらかじめボタンやパネルなどを配置するときに 背景色の変更のように背景に画像を設定することはできないのでしょうか? できなければmファイル内でのプログラミングでもいいので 画像ファイルを読み込んでGUIで背景表示させる方法を教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
Kules Part6です。 >贅沢をいうとボタンではなく本当はテキストのようなクリックしても何も反応しない箇所に画像を表示させたいのですが あ…そうなんですか(笑)だとしたらいちいちuicontrolを持ちださなくてもできますね。 ちなみにですけど、テキストはエディット(コールバックが設定できる)ではなくテキスト(コールバックは設定できない。CreateFcnとDeleteFcnは設定できる)なんですよね? だとしたら、「uicontrolのテキストの背景に画像を付ける」よりは「画像の上にテキストを貼り付ける」方が簡単そうです。(同じと思われるかも知れませんが、操作としては似て非なるものです) 「 function h_t=SetFigure(handle) h_sp=axes('Parent',handle); Crgb=imread('Test.png'); S=size(Crgb); image(Crgb); set(h_sp,'Unit','Pixels','Position',[200,200,S(2),S(1)],'Unit','Normalized'); set(h_sp,'Visible','Off'); set(handle,'Position',[200,200,S(2)+400,S(1)+400]); h_t=text(0,S(1)/2,'Test','FontSize',50,'Parent',h_sp); set(h_sp,'HandleVisibility','off'); 」 Test.pngはrgbのトゥルーカラーで出来ていることを前提で書いています。もしインデックスカラーだとしたら前回書いたようにind2rgbなどを使ってやればよいです。 「」の中身をパスが通っているところ(My Documents\Matlabがオススメ)に保存して下さい。 その後、 figure(1); set(gcf,'CreateFcn','h_t=SetFigure(gcf);'); としたfigureを適当な名前(拡張子は.fig)で保存すると、 そのfigureを開いた時にSetFigureが実行され、 画像ファイルが貼り付けられたaxesが1つでき(Figureの中央で、余白が上下左右に200ピクセルずつできる)、 その画像の中にフォントサイズ50の「Test」の文字(横幅ははみ出したりするかも)が画像ファイルの上下中央、左詰めで出ます。 途中のset(h_sp,'HandleVisibility','Off')はズームインやズームアウト(figure上部の虫眼鏡の形をしたアイコンなどでの操作)がきかないようにするためと、新たなグラフが勝手に描かれるのを防ぐためにつけています。 set(h_sp,'Visible','off')は軸の枠線を消すためのものです。 さらに、Textハンドルはh_tという変数で出力されるため、 set(h_t,'String','HogeHoge'); とすれば文字列を変更できます。 他にも色々なものはいじれますが、どのようなニーズがあるのかわからないとここには書ききれないので省略します。 方針を大きく変えたので「???」となるかも知れません。 さっぱりわからない/テキストで操作したいプロパティがあるがどうすればいいのかわからない/私の書いたとおりやったのにエラーが出た/表示がおかしいなどありましたら補足願います。 参考になれば幸いです。
その他の回答 (5)
- Kules
- ベストアンサー率47% (292/619)
Kules Part5です。 >画像を表示することができました! うまくいったようで何よりです。 しかしGUIDEの中では動作しないのはおかしいですね。 しかも「機能しない」というのはエラーが出るわけでもないんですよね? 私の環境では何の問題もなく画像をuiに貼り付けることができたんですが。 とりあえず3点確認してみてください。 1. 色々調べたところ、uicontrolのstyleによってCdataの影響は変わるようです。 ・PushButton,ToggleButtonはCdataが反映される ・RadioButton,CheckBoxもCdataが反映されるが、クリックした時の外観の変化(チェックボックスにチェックが入るとか)はなくなる ・Edit,Text,Slider,Frame,Listbox,PopupmenuはCdataが反映されない したがって、プッシュボタン、トグルボタン、ラジオボタン、チェックボック以外は Cdataをいじっても無意味です。まずここは満たしていますでしょうか? 2. CreateFcn中の [C map]=imread('ファイル名'); Crgb=ind2rgb(C,map); set(h_u,'Cdata',Crgb); の後に、 disp(size(Crgb)); を追加して下さい。これで、CreateFcnがちゃんと実行されていて、 Crgbも読み込まれているなら.figのファイルを開いた時に コマンドウィンドウに 画像サイズ(2要素),3 と表示されるはずです。されない場合はCreateFcnが実行されていないということです。 また、プログラム中にh_uがいますがこれはどこかで定めているんでしょうか? (まあ多分h_uの所は本来のプログラムではhObjectを使っているんだと思いますが) 3. Cdataを操作するuicontrolのプロパティのうち、tagを確認して下さい。 (プロパティインスペクタから見れます) ここでは説明のためにtagが'pushbutton1'だとします。 figファイルを開いた後、 set(0,'ShowHiddenHandle','On'); h=findobj(0,'Tag','pushbutton1'); c=get(h,'cdata'); set(0,'ShowHiddenHandle','Off'); をコマンドウィンドウ上で実行して下さい。 ちゃんと画像ファイルが設定されているなら画像サイズ×3の3次元行列が cに出力されます。cが空行列の場合はcdataが設定されていません。 お手数かけますが、以上3点確認して、解決しないようでしたらまた補足願います。 参考になれば幸いです。
- Kules
- ベストアンサー率47% (292/619)
Kules Part4です。 やはりトゥルーカラーしか受け付けてくれませんか… と思ってたらind2rgbの存在を思い出しました。(普段全く使わないのですっかり忘れてました…) Crgb=ind2rgb(C map); でインデックスのカラーデータCとカラーマップmapから RGB行列の3次元行列を作ってくれます。 ちなみにですが逆もあります (Cind=rgb2ind(Crgb,n);nはカラーマップの最大のインデックスを決めます) とりあえず[C map]=imread('ファイル名'); Crgb=ind2rgb(C,map); set(h_u,'Cdata',Crgb); とすればボタンに画像の表示はできそうですね。 >白黒で画素が拡大されたような感じだったのですが のうち「白黒」はind2rgbで直すなり、figureのカラーマップを読み出したmapにするなりすれば解決しそうです。 (私の勉強不足でimshowという関数を知らないんですが、インデックスカラーをうまいことカラーの画像にしてくれる関数みたいですね) 「画素が拡大」は画像を貼り付ける箇所のサイズとC行列のサイズが合ってないのでしょう。 特に私がよくミスするのがサイズの決め方です。 画像をfigureに(というかaxesに)貼りつける時、画像サイズは(縦×横) で決めるのに対し、axesの位置は[右,上,幅,高さ]で決めます。 ということは今回の画像サイズが縦53×横630なので、 画像を貼り付ける軸を set(gca,'Unit',Pixels','Position',[0,0,53,630],'Unit',Normalized');と決めてしまうと横にすごく引き伸ばされた画像になります。 set(gca,'Unit',Pixels','Position',[0,0,630,53],'Unit',Normalized');が正しいですね。 ちなみに最初の2つ[0,0]はボタンの左下隅がfigureの左下隅からどれだけ離れているかをピクセル値で決めています (デフォルトの設定では。Unitプロパティをいじっている時はその限りではありません) 以上のことを踏まえて試してみてください。うまくいかなければ再度補足願います。 参考になれば幸いです。
補足
ありがとうございます。 figure(1);set(gcf,'Position',[200,200,500,600]); h_u=uicontrol('Style','PushButton'); set(h_u,'Unit','Pixels','Position',[0,0,350,250]) [C map]=imread('ファイル名'); Crgb=ind2rgb(C,map); set(h_u,'Cdata',Crgb); で画像を表示することができました! ただ、本当にやりたいのは.FigファイルのGUIDE内で 初期状態から画像が表示されるようなもので CreateFcn内に同様に [C map]=imread('ファイル名'); Crgb=ind2rgb(C,map); set(h_u,'Cdata',Crgb); と記述しても機能しません。 StringやValueは同じオブジェクトでも機能するのですがCdataだけは動作しません。。。
- Kules
- ベストアンサー率47% (292/619)
三度Kulesです。 何も変わらなかったんですか…これは確認しなければならないことがたくさんありそうですね。 考えられそうな原因を2つほど挙げてみます。 1.CreateFcnが動作していない GUIDEを用いてインターフェースを作成している場合、CreateFcnが動作するのはmファイルを実行した時か、figファイルを開いた時だったと思いますが、どのような順序でしているかは私は知りません。 まず、ボタンのプロパティをプロパティエディタで調べて下さい。CreateFcnにちゃんと関数ハンドルが入っているでしょうか? もし入っているなら、CreateFcn中にブレイクポイントを仕掛けるという手をありますが、実際普通の状態でCdataが正しく設定できるかを確かめた方が早いです。 私が前回書いたサンプルのclose 1以降で、set(h_u,'Cdata',imread('Test.jpg'));の'Test.jpg'を今貼り付けたい画像ファイルの名前にしてみて下さい。それで動作しますか? 2.画像ファイルとボタンのサイズが違いすぎて、またグレースケールの画像なのでたまたま何も変わっていないように見える 画像ファイルをボタンのサイズに合わせて拡大・縮小をしてくれるといった親切なことはしてくれないみたいです。 ボタンのサイズをなるべく大きくしてみてください。それで何か変わりませんか? また、 >imreadで画像を読み込むとグレースケールでかなり荒い画像になる 件について。 グレースケールになるのは画像のカラー設定が24ビットとかではないからだと思います。カラーインデックスのみ登録されていて、カラーマップを参照しながら色を決めるようなパターンですね。 とりあえずC=imread('ファイル名'); としてCのサイズを調べてみてください。(~×~×3 uint8)になっていますか? なっていなければ[C map]=imread('ファイル名');としてカラーマップを取得して、figure propertyに設定する必要があります。 次に画像が粗い件ですが、何を(どんなファイル(画像のサイズとか種類とか))をどこに(figure?)表示させると粗い画像になるんですか? どのような操作をした結果画像を粗いと判断しているのかわからないと原因は特定できません。 ひとまず上記1.2.と、あとCのサイズを調べて補足願います(画像が粗い件についても)。 その辺りがわかればもう少し有益な回答ができるかも知れません。 参考になれば幸いです。
補足
close 1以降のプログラムだと uicontrol の CData プロパティはトゥルーカラーでなければなりません というエラーが出ました。 元画像はカラーなのですがimreadで値を見ると2次元配列になっています。 [C map]では Cが53×630 unit8 mapが256×3 となっています。 粗いというのは白黒で画素が拡大されたような感じだったのですが 今日imshowで確認するとしっかりと画像が表示されました。 原因はよく分かりませんが、とりあえず画像が表示されるようにしたいです。。。
- Kules
- ベストアンサー率47% (292/619)
再びKulesです。 >MATLABで普通のプログラミングはやっているのですがGUIのようなインターフェースに系に関しては初めてなものなので、 という方にはかなり難儀な要求ですね…去年の私だと諦めてしまうかもしれません。 といっても私自身もMatlab歴はまだ2年足らずなんですが(笑) とりあえずイメージしにくいと思うんでサンプルを書いてみます。コマンドライン上で実行するか、適当なmファイルを作って実行して下さい。(現在Matlabが動く環境にいないのでエラーが出るかも知れません。もし出たらごめんなさい) figure(1);set(gcf,'Position',[200,200,350,250]); plot(-1:1e-3:1,(-1:1e-3:1).^2,'LineWidth',3); set(gca,'Position',[0,0,1,1]); C=getframe(gcf);%(1) imwrite(C.cdata,'Test.jpg');%(2) close 1; figure(1);set(gcf,'Position',[200,200,500,600]); h_u=uicontrol('Style','PushButton'); set(h_u,'Unit','Pixels','Position',[0,0,350,250]) set(h_u,'Cdata',imread('Test.jpg'));%(3) figureの左下隅に書かれたちょっと大きめのボタンに放物線のグラフが出たでしょうか? もし出なかったらその旨補足願います。 ここでワークスペースには変数Cがあると思います。種別はstructになっています。これを変数エディタで見てやると、フィールドがcolormapとcdataから構成されています。 このcdataがRGBの3次元行列になっています。 %(2)の行でそのcdataをTest.jpgという名前で保存しています。 %(3)の行でTest.jpgを読みだしています。imreadは複数の出力を持つこともできますが、出力形式を指定せずに使った場合はRGBの3次元行列、またはグレースケールの2次元行列を出力します。 つまり、%(3)の行でボタンに画像ファイルを貼り付けたことになります。 サンプルではウダウダ書きましたが、大事なのは%(3)の行だけです。というかそれより前はTest.jpgという画像ファイルを作るための前置きですし。 imreadでは上にも書いた通り基本はRGBの3次元行列です。bmp,jpg,png辺りでは、ほぼ間違いなく3次元行列で出てくるはずです。TIFFなどを使うと違うかも知れません。 CreateFcnはそのオブジェクトを作る時に問答無用に呼び出される関数ですので、その中で set(hObject,'Cdata',(画像のファイル名)); とすれば背景に画像ファイルが設定できます。 ただ、ボタンのサイズと画像のサイズがピクセル単位で合っていないと端が切れたり周りに空白ができたりします。これの回避方法は私にもわかりません。(修行不足です…) エラーが出たとか、さっぱりわからないとかありましたら補足願います。 参考になれば幸いです。
補足
つまりは、あるオブジェクトのCreateFcnに set(hObject,'Cdata',imread('ファイル名')); とするだけでそのオブジェクトの背景が画像になるわけですよね? やってみたのですがエラーは出ませんが、何も変わりませんでした。 それとimreadで画像を読み込むとグレースケールでかなり荒い画像になるのですが 何かオプションが必要ですか? 何度もすみません。
- Kules
- ベストアンサー率47% (292/619)
フォルダ内の…というとどうするかは使う人次第ですが、背景に画像を設定することは可能です。 まず、uicontrolの場合プロパティとしてcdataを持っていますので、 そこにRGBからなる3次元行列を設定してやればよいです。 パネルの場合はcdataを持っていませんので、パネルの大きさぴったりのaxesを設定してやって、 (axes('Parent',(uipanelのハンドル),'Position',[0,0,1,1])とか) そこにimageを使って画像を描いてやればよいかと。(というか私にはそれ以外の方法が思いつきません…) おそらく何か動作させて画像を貼り付けるというよりは、 デフォルトで画像が設定されていて欲しいんですよね? GUIDEを使うなら、各オブジェクトに対してCreateFcnを設定できる(オブジェクトを右クリック→コールバックの表示→CreateFcnでmファイル内のCreate関数が書かれているところに移動します。もしなければ新たに作られます)ので、そこに上記の通り画像を設定するように書いてやればよいかと。 もし貼り付ける画像をそのたび選びたいというのであればuiloadやuigetfileで必要なファイルをその都度選択できるようにするとか、uimenu内に「背景の設定」みたいな項目を作ってそこで画像を呼び出せるようにしてもいいかも知れません。 さらっとこうすればってのを書きましたが、「だからそれをどうやって書いたらいいんだよ!」というお叱りも受けそうな回答ですね。ただ、これ以上の詳細な説明はどのようなことをしたいかによって変わってきますので。 「情報足りねーよ!」という場合はその旨補足いただければと思います。 参考になれば幸いです。
補足
詳細な説明ありがとうございます。 MATLABで普通のプログラミングはやっているのですがGUIのようなインターフェースに系に関しては初めてなものなので、仕組みを理解していません。 動作などではなく、単純にある画像をずっと表示させておきたいだけです。 いうなればテキストのような部分に文字ではなく画像を表示させるだけです。 cdataの中身ですが式、サイズのように出てきました。 サイズで配列が変更されるようですが、RGBを直接入れなければいけませんか? 式にはimread(ファイル名)のような関数を入れるのかと思いましたができませんでした。 Create関数からも文字の表示はSet(Object, 'String'・・・)など分かるのですが 画像になると分かりません。 お時間のあるときでいいので補足頂ければと思います。
補足
何度も詳細な説明ありがとうございます。 原因は1でした。 textやeditで何も反応していなかったのですがpushbuttonで表示することができました。 サイズを合わせてトゥルーカラー表示も問題なくすることができました。 GUIや画像に関する配列の意味も少しづつ理解してきました。 贅沢をいうとボタンではなく本当はテキストのようなクリックしても 何も反応しない箇所に画像を表示させたいのですが Cdataに入れても意味がないということは別の変数がその役割をもっているのでしょうか? それともそもそも画像表示は不可能ということでしょうか? 別のFigureで作ったもののPositionを移動させるか (別の一方のFigureの中に組み込めるか不明ですが) 他に代替できる機能はありますか?