Matlab GUI图像保存问题

    技术2022-05-12  23

     

    在做gui界面的时候遇到一个这样的问题:我fig里有2个axes,一个用于显示原始图像,一个用来显示每个步骤处理结果。想通过一个菜单或者按键来实现保存处理结果的功能,也就是说只要用户点击保存的时候。系统会读取axes2里的图像数据,然后写成文件。因为保存路径和文件名可供用户选择,所以很自然想到uiputfile和saveas(看过很多人写的程序都是这样的)。由于保存程序和处理程序不在一个callback里所以牵扯到数据的传递问题,此问题困扰我好久了,今天总算给解决了。拿来分享一下,同时又发现了新问题,高手们来帮忙哈。

    因为在多个axes情况下,显示不同的图像实现的代码记得是eight兄给的:

       axes(handles.axes1);

       这以后的绘图或者显示函数都是针对axes1的

       axes(handles.axes2);

       这以后的绘图或者显示函数都是针对axes2的

       .......................................

       更多的一次类推.....

    那么如果向保存axes2的图像该怎么实现呢?受上边的启发我用了下边的代码:

       [sFileName sFilePath]=uiputfile({'*.jpg','JPEG-Files (*.jpg)'; ...

                '*.*','All Files (*.*)'},'保存图像文件','untitled.jpg');

       if ~isequal([sFileName,sFilePath],[0,0])

          sFileFullName=[sFilePath sFileName];

          axes(handles.axes2);

          saveas(gca,sFileFullName,'jpg');

       else

          msgbox('你按了取消键!','保存失败');

       end

    程序运行正常,可惜结果不对。保存的图像是整个fig的左下角的一部分,而不是axes2里显示的图像。

    猜测可能是数据传递有问题,结果把我搜集的参数传递方式试了一个遍:

          handles.Timg=imshow(J);%某论坛一个版主给的方法

          handles.Timg=J;%常用的保存方法

    事实证明这2种方法传递的句柄保存的结果都不太正常,而且和我上边使用的方法结果完全相同!

    无奈之下,想到高手常用的另一种传递方法setappdata和getappdata

          setappdata(gcf,'Timg',J);

    保存里callback里:

          data=getappdata(gcf,'Timg');

          saveas(Timg,sFileFullName,'jpg');

    结果程序出错:

    ??? Error using ==> saveas

    Invalid handle.

    Error in ==> preprocess>saveas_Callback at 206

        saveas(data,sFileFullName,'jpg');

    Error in ==> gui_mainfcn at 75

            feval(varargin{:});

    Error in ==> preprocess at 42

        gui_mainfcn(gui_State, varargin{:});

    ??? Error while evaluating uimenu Callback.

    无效的句柄,查看saveas的help文档,发现saveas保存的都是句柄对象。getappdata获得是图像数据,原来是因为saveas不支持保存图像数据,所以想到了imwrite

        data=getappdata(gcf,'Timg');

        imwrite(gca,sFileFullName,'jpg');

    嘿嘿程序完全正常了,经常见到uiputfile和saveas一起用。和imwrite一起用的倒是没见过,可能是我见识太少了。后来发现当使用imwrite保存的时候,在处理的callback里可以用handles.Timg=J替换 setappdata(gcf,'Timg',J);

       虽然达到了保存的目的但是,问题仍在:如何用saveas得到正确的结果?3种不同的句柄出传递方法得到相同不正确的结果,说明问题不在句柄保存本身上,那么到底是在哪儿呢?还往高手们多讨论一下,把多axes的图像的可选路径保存问题弄个一目了然!

       附图是用imwrite和saveas的保存结果,以后整个figure的图像。

    下面的小程序是用来测试imwrite和saveas保存图像的区别:

    ==================================================================================

    I=imread('lena.bmp');

    data=imadjust(I);

    imshow(data);

    pause;

    %%下面是只有单个绘图窗口的情形

    [sFileName sFilePath]=uiputfile({'*.jpg','JPEG-Files (*.jpg)'; ...

                '*.*','All Files (*.*)'},'保存图像文件','untitled.jpg');

    if ~isequal([sFileName,sFilePath],[0,0])

        sFileFullName=[sFilePath sFileName];

        imwrite(data,sFileFullName,'jpg');

    end

    pause;

    [sFileName sFilePath]=uiputfile({'*.jpg','JPEG-Files (*.jpg)'; ...

                '*.*','All Files (*.*)'},'保存图像文件','untitled.jpg');

    if ~isequal([sFileName,sFilePath],[0,0])

        sFileFullName=[sFilePath sFileName];

        saveas(gca,sFileFullName,'jpg');

    end

    pause;

    %下面是多个绘图窗口的情形(以2个为例)

    subplot(121),Ta=imshow(data);title('原图')

    [counts,x] = imhist(data);

    subplot(122),Tb=plot(x,counts);title('直方图')

    saveas(Tb,'直方图.jpg');

    %这里的保存结果是整个fig,需要的是子图2里的直方图。

    ==================================================================================

    直观上看有2点不同

    (1)saveas保存的图像是整个fig,图像以外的部分全部用白像素代替了。

    (2)图像的大小不一样:

            saveas: 1201*900*24b jpeg  72.3k

            imwrite:256*256*256  jpeg  12.6k

    (我的lena.bmp是重新在网上下载的,系统里的没了。所以具体的数据会有差别,在此只是为了说明2者保存同种类型图像时的区别)

    最后归纳一下待解决的问题:

    (1)如何在gui里用saveas正确的保存不同axes里的图像?

    (2)在多窗口绘图里(使用subplot的情形),如果正确保存子图里的图像?

    screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='点击在新窗口查看全图/nCTRL+鼠标滚轮

    放大或缩小';}" border=0>


    最新回复(0)