图像保存问题,欢迎讨论!
在做gui界面的时候遇到一个这样的问题:我fig里有2个axes,一个用于显示原始图像,一个用来显示每个步骤处理结果。想通过一个菜单或者按键来实现保存处理结果的功能,也就是说只要用户点击保存的时候。系统会读取axes2里的图像数据,然后写成文件。因为保存路径和文件名可供用户选择,所以很自然想到uiputfile和saveas(看过很多人写的程序都是这样的)。由于保存程序和处理程序不在一个callback里所以牵扯到数据的传递问题,此问题困扰我好久了,今天总算给解决了。拿来分享一下,同时又发现了新问题,高手们来帮忙哈。因为在多个axes情况下,显示不同的图像实现的代码记得是eight兄给的:
axes(handles.axes1);
这以后的绘图或者显示函数都是针对axes1的
axes(handles.axes2);
这以后的绘图或者显示函数都是针对axes2的
.......................................
更多的一次类推.....
那么如果向保存axes2的图像该怎么实现呢?受上边的启发我用了下边的代码:
=uiputfile({'*.jpg','JPEG-Files (*.jpg)'; ...
'*.*','All Files (*.*)'},'保存图像文件','untitled.jpg');
if ~isequal(,)
sFileFullName=;
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;
%%下面是只有单个绘图窗口的情形
=uiputfile({'*.jpg','JPEG-Files (*.jpg)'; ...
'*.*','All Files (*.*)'},'保存图像文件','untitled.jpg');
if ~isequal(,)
sFileFullName=;
imwrite(data,sFileFullName,'jpg');
end
pause;
=uiputfile({'*.jpg','JPEG-Files (*.jpg)'; ...
'*.*','All Files (*.*)'},'保存图像文件','untitled.jpg');
if ~isequal(,)
sFileFullName=;
saveas(gca,sFileFullName,'jpg');
end
pause;
%下面是多个绘图窗口的情形(以2个为例)
subplot(121),Ta=imshow(data);title('原图')
= imhist(data);
subplot(122),Tb=plot(x,counts);title('直方图')
saveas(Tb,'直方图.jpg');
%这里的保存结果是整个fig,需要的是子图2里的直方图。
==================================================================================
直观上看有2点不同
(1)saveas保存的图像是整个fig,图像以外的部分全部用白像素代替了。
(2)图像的大小不一样:
saveas: 1201*900*24b jpeg72.3k
imwrite:256*256*256jpeg12.6k
(我的lena.bmp是重新在网上下载的,系统里的没了。所以具体的数据会有差别,在此只是为了说明2者保存同种类型图像时的区别)
最后归纳一下待解决的问题:
(1)如何在gui里用saveas正确的保存不同axes里的图像?
(2)在多窗口绘图里(使用subplot的情形),如果正确保存子图里的图像?
[ 本帖最后由 eight 于 2007-7-20 14:54 编辑 ] 原帖由 花如月 于 2007-7-20 09:26 发表 http://www.chinavib.com/forum/images/common/back.gif
在做gui界面的时候遇到一个这样的问题:我fig里有2个axes,一个用于显示原始图像,一个用来显示每个步骤处理结果。想通过一个菜单或者按键来实现保存处理结果的功能,也就是说只要用户点击保存的时候。系统会读 ...
saveas、print 应该不能实现各个子图的保存功能,因为它们的操作对象仅仅是整个figure:
You can pass the handle of any Handle Graphics object to saveas,
which then saves the parent figure to the object you specified should h not
be a figure handle. This means that saveas cannot save
a subplot without also saving all subplots in its parent figure
至于为何出现保存左下角的问题,我想是这样的:调用这两个函数保存图片时,系统先检测axes,一旦检测到某个axes对象,就马上输出该axes的内容,直到figure的底部
[ 本帖最后由 eight 于 2007-7-20 15:03 编辑 ] 原帖由 花如月 于 2007-7-20 09:26 发表 http://www.chinavib.com/forum/images/common/back.gif
在做gui界面的时候遇到一个这样的问题:我fig里有2个axes,一个用于显示原始图像,一个用来显示每个步骤处理结果。想通过一个菜单或者按键来实现保存处理结果的功能,也就是说只要用户点击保存的时候。系统会读 ...
三种参数传递的方式我都试了,貌似没有问题,得到的图片都是一样的
回复 #3 eight 的帖子
谢谢eight兄的回复,那么我的第一问题看来只能用uiputfile和imwrite来实现了。(2)在多窗口绘图里(使用subplot的情形),如果正确保存子图里的图像?反正是讨论,大家就都发表一下自己的想法。(除了使用抓图工具) 原帖由 花如月 于 2007-7-20 09:26 发表 http://www.chinavib.com/forum/images/common/back.gif
在做gui界面的时候遇到一个这样的问题:我fig里有2个axes,一个用于显示原始图像,一个用来显示每个步骤处理结果。想通过一个菜单或者按键来实现保存处理结果的功能,也就是说只要用户点击保存的时候。系统会读 ...
imwrite 和 saveas 两者保存的图片是不同的,因为前者保存的对象只是图象的数据,而后者是窗口的句柄,因此,前者生成图片的大小与原始矩阵大小一致,比较准确些,而后者保存的对象窗口的客户区部分,并且保存时会拉伸到某个固定大小,因此当图片比较大的时候,用 saveas 或者 print 保存会出现“图片缩小保存”的警告语句。 原帖由 花如月 于 2007-7-20 15:14 发表 http://www.chinavib.com/forum/images/common/back.gif
谢谢eight兄的回复,那么我的第一问题看来只能用uiputfile和imwrite来实现了。
(2)在多窗口绘图里(使用subplot的情形),如果正确保存子图里的图像?反正是讨论,大家就都发表一下自己的想法。(除了使用抓 ...
如果 subplot 中画的是图片,则通过 CData 属性就可以使用 imwrite 保存了:
a=get(gca);
b=get(a.Children);
imwrite(b.CData, filename);如果画的并非图片,例如在你的例子中使用 plot 作的图,则我暂时想不到如何保存下来
回复 #6 eight 的帖子
非常感谢eight兄,又学了一招:loveliness:回复 #6 eight 的帖子
刚才试了一下,发现这种方法保存的都是最后一个子图。中间的子图是不是也没有办法保存? 原帖由 花如月 于 2007-7-21 20:37 发表 http://www.chinavib.com/forum/images/common/back.gif刚才试了一下,发现这种方法保存的都是最后一个子图。中间的子图是不是也没有办法保存?
不是啊,你试试以下代码:
function Untitled9
I=imread('cameraman.tif');
data=imadjust(I);
subplot(121),ta = imshow(data);title('原图')
filename = 'org.jpg';
mysaveas(filename,ta);
= imhist(data);
subplot(122), tb = plot(x,counts);title('直方图')
filename = 'hist.jpg';
mysaveas(filename,tb);
function mysaveas(filename,h)
a=get(gca);
b=get(a.Children);
if isfield(b, 'CData')
imwrite(b.CData, filename);
else
end
else 那里是 plot 出来的图片保存问题,还没有想到解决方法。其实此时 b 虽然没有 CData 域,但是却在 XData, YData 中保存了 plot 的数据,不知道能否作为图片save下来 发现这种情形,似乎没有办法得到更多子图的数据:
freqs(1,)
a=get(gca);
b=get(a.Children);
figure,loglog(b.XData,b.YData);
只画出了第一个子图,第二个子图没法得到数据。不知到还有没有别的办法?虽然意义不大,不过有时还是会碰到别人保存好的fig图形。如果有多个子图,又需要读出数据。那么能找到直接读的方法就最好不过了 GUI保存图片我一般用PRINT语句。
建立一个隐藏的FIGURE。通过设置FIGURE大小,设置保存图片大小
可以通过COPY AXES的办法实现隐藏的FIGURE到任意子图的映射。
此方法可以方便建立一如SaveAxes(AxesHandle,Filename)的函数。 '''''function Untitled9
I=imread('cameraman.tif');
data=imadjust(I);
subplot(121),ta = imshow(data);title('原图')
filename = 'org.jpg';
mysaveas(filename,ta);
= imhist(data);
subplot(122), tb = plot(x,counts);title('直方图')
filename = 'hist.jpg';
mysaveas(filename,tb);
function mysaveas(filename,h)
a=get(gca);
b=get(a.Children);
if isfield(b, 'CData')
imwrite(b.CData, filename);
else
end''
%%%%%%%%%%%%%%%%%%%%%%%%%%555
%%%%%%%%%%%%%%%%%%%%%%55
以上eight院长的程序
我试了一下
在我的版本上保存有点问题
下面是我保存gui界面上axes中图形的思路
虽然路子有点弯
但功能基本能够实现
与大家讨论
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
由于saveas保存的是figure中的图形,所以在gui界面中axes显示的图形保存的话,我用的版本上老出现问题
自己就想了别的招:先获得axes中图形的:label、labeltick、axis、title、data、view等值
新建figure
绘图
保存
pause
关闭
就能完成axes当前图形的保存,走了弯路但可以解决问题。
%%%%%%%%%%%%%%%%%%%%%5
我觉得junzifei的方法可用于保存plot命令的图片
rt,如果在读入的图片上做图,这样就会生成一个内部矩阵,如果能得到这个矩阵及其相关参数,我觉得就可以保存下用plot命令做出的图,不知道各位的是否同意? 路过,学习了! GUI中axes1中的图像怎么保存? saveas(gca,sFileFullName,'jpg');好像只能保存右下角,而data=getappdata(gcf,'Timg');imwrite(gca,sFileFullName,'jpg');却什么都没有。。。这是为什么,求指导啊,谢谢大大
页:
[1]