问题
I have a set of polygon vertices in in X, Y matrices and their colors are in RGB values in another matrix C.
I then use fill() function to generate patch objects that is displayed in a Matlab figure.
I want to create a bmp object from this figure. What I mean by a bmp object is the x,y coordinates of the pixels and there RGB values.
If I use the print() function, with '-dbmp' and a file name, matlab can write the bmp to a file. But then I have to read the file with imread() to create the bmp object.
Is there a way to create the bmp object without writing and reading to from a file?
Becauswe I have to perform this operation many times and writing and reading to file is time consuming and will reduce the life time of my disk too I guess.
Edit: code after editing according to answer
N = 5;
Tri = 100;
res = 200; %200 pixles per inch
G = zeros(Tri,9,N);
X = 2*rand(Tri,3,N);
Y = 2*rand(Tri,3,N);
R = randi([0 255],Tri,N)/255;
G = randi([0 255],Tri,N)/255;
B = randi([0 255],Tri,N)/255;
for c1=1:N
G(:,1:3,c1)= X(:,:,c1);
G(:,4:6,c1)= Y(:,:,c1);
G(:,7,c1)= R(:,c1);
G(:,8,c1)= G(:,c1);
G(:,9,c1)= B(:,c1);
end
for c2=1:N;
h = figure('Visible','off');
set(h, 'PaperUnits', 'inches', 'PaperPosition', [0 0 400 400]/res);
for c3 =1:Tri
h1 = fill(G(c3,1:3,c2), G(c3,4:6,c2), [G(c3,7,c2) G(c3,8,c2) G(c3,9,c2)]);
set(h1,'EdgeColor','None');
hold on;
end
%print(h,'-dbmp',['-r' num2str(res)],['file' num2str(c2)]);
F = getframe(h);
[a, b] = frame2im(F);
Tmp_v1 = a;
Tmp_v1 = Tmp_v1(:);
Norm_v1(c2) = norm(single(Tmp_v1));
end
Thank you.
回答1:
If you have the current figure open, you can try the getframe idiom. Once you have access to this, you can access the frame's image data by looking at the cdata
field in the structure. After you have this, you can use the imwrite command from MATLAB's image processing toolbox (let's hope you have it...) to write the image to file.
Here's an example:
x = 1 : 5;
y = 1 : 5;
plot(x,y); %// Plot a line
h = getframe;
img = h.cdata;
imwrite(img, 'testFrame.bmp');
This should be able to grab what is inside the current figure and save it to file. In this case, this will be a straight line from (x,y) = (1,1)
to (x,y) = (5,5)
, with a slope of 1. Bear in mind that this won't save the title of the graph or the axes. This will only grab what is rendered inside the frame.
Edit from comments
Now that I know what you're really after, you want to generate a bunch of random polygons, then extract just the core image, without any axes or tick marks and so on. You'll have to modify your for
loop where you're creating the images so that you want the figure to fill the entire window without any gray padding You'll also want to turn off the axis too. Also, when you're generating each image, you'll need to turn off the ticks. This is done with a combination of not writing any tick labels, as well as setting the tick length to 0. In other words, you'll need to modify your code so that it looks like this. You'll see where I inserted code by seeing the %// NEW
statements in your code:
for c2=1:N;
h = figure('Visible','off');
subplot('position', [0 0 1 1]); %// NEW
axis off; %// NEW
set(h, 'PaperUnits', 'inches', 'PaperPosition', [0 0 400 400]/res);
for c3 =1:Tri
h1 = fill(G(c3,1:3,c2), G(c3,4:6,c2), [G(c3,7,c2) G(c3,8,c2) G(c3,9,c2)]);
set(h1,'EdgeColor','None');
set(gca,'xcolor','w','ycolor','w','xtick',[],'ytick',[]) %// NEW
set(gca,'Ticklength',[0 0]); %// NEW
hold on;
end
%print(h,'-dbmp',['-r' num2str(res)],['file' num2str(c2)]);
F = getframe(h);
close all; %// NEW
[a, b] = frame2im(F);
a = imresize(a, [400 400], 'nearest'); %// NEW
Tmp_v1 = a;
Tmp_v1 = Tmp_v1(:);
Norm_v1(c2) = norm(single(Tmp_v1));
end
This will still show you the frames being popped up for each image you're creating, but you should be able to get just pure image data at this point. Note that the images are still coming out as a bit larger than 400 x 400
. This is due to the fact that once we have removed the borders and the tick marks and so on, the figure will stretch to fill the entire figure. To get around this, I use imresize and shrink the images back down to 400 x 400
as per your desired size.
Also, take note that every time you generate a new image, a new figure is spawned. Every time you call getframe
, the figure with this randomly generated polygon image pops up, and getframe
takes a snapshot of that current frame. There isn't a way to prevent this from happening, as you won't be able to take a snapshot of that figure. One way to get around this would be to close the figure after you grab the image. You can do a close all;
after each call to getframe
. That way, only one figure gets shown at any one time, but this still won't prevent the figure from showing up.
If I do find a solution to this, I'll let you know!
来源:https://stackoverflow.com/questions/25725408/create-a-bitmap-from-patch-object-in-matlab