all groups > dotnet drawing api > july 2004 >
You're in the

dotnet drawing api

group:

image graphics drawing confusion


image graphics drawing confusion cwineman
7/29/2004 4:22:11 PM
dotnet drawing api:
Below I list two methods that are part of my application. I don't understand
why, in the AddEyeMarkers() method, both versions of the newImage object
that I am saving don't contain ellipses that I have drawn using the
Graphics.FromImage( newImage ) object.

I expected newImage1.jpg to be the same size as m_originalImage, but with
two ellipses drawn on it. I expected newImage2.jpg to be a thumbnail version
of newImage1.jpg. Instead, newImage2.jpg is scaled thumbnail version, but
missing the ellipses (In other words, a thumbnail version of
m_originalImage ). How come?

The overall mission is to get a scaled-down, eye-marked version of the
original image, and stick it in a PictureBox on my form.

Can anyone see what I am doing wrong? If this was to confusing to follow,
let me know and I will try to rephrase my problem.

Thanks,

-cwineman


/// Simply supposed to take an original image and create a scaled-down
thumbnail version of the /// image that will fit in a PictureBox control.
private Image AdjustImageSize( Image image )
{
int maxSize = PICTURE_BOX_WIDTH;
int oldWidth = image.Width;
int oldHeight = image.Height;
int newWidth = oldWidth;
int newHeight = oldHeight;

if( oldWidth > maxSize || oldHeight > maxSize )
{
if( oldWidth > oldHeight )
{
newWidth = maxSize;
newHeight = (oldHeight * maxSize) / oldWidth;
}
else
{
newHeight = maxSize;
newWidth = (oldWidth * maxSize) / oldHeight;
}
}
return image.GetThumbnailImage( newWidth, newHeight, null, IntPtr.Zero );
}


/// Makes a clone of original image(Since I don't want to mess up the
original.
/// Gets the graphics of the clone and draws some circles. (These circle
represent eye
/// positions)
/// Save two different versions of newImage.
/// Set the pictureBox control so that it shows original picture, but now
adjusted to fit
/// properly and now with eyes marked.
private void AddEyeMarkers()
{
Image newImage = (Image) m_originalImage.Clone();
Pen pen = new Pen( Color.Red, 2f );
Graphics graphics = Graphics.FromImage( newImage );
graphics.DrawEllipse( pen, (_leftEye.X - 10), (_leftEye.Y - 10), 20, 20 );
graphics.DrawEllipse( pen, (_rightEye.X - 10), (_rightEye.Y - 10), 20,
20 );

newImage.Save( "c:\\temp\\newImage1.jpg",
System.Drawing.Imaging.ImageFormat.Jpeg );

newImage = AdjustImageSize( newImage );
newImage.Save( "c:\\temp\\newImage2.jpg",
System.Drawing.Imaging.ImageFormat.Jpeg );

pictureBox.Image = newImage;
}

Re: image graphics drawing confusion Bob Powell [MVP]
7/30/2004 1:07:51 AM
I think this problem comes from the fact that your AdjustImageSize routine
gets a thumbnail image. This isn't drawn from the bits you've modified but
from the thumbnail that already exists in the jpeg file.

Rather than use the GetThumbnailImage method, create your own thumbnail by
drawing the image to a correctly sized memory bitmap.

--
Bob Powell [MVP]
Visual C#, System.Drawing

The Image Transition Library wraps up and LED style instrumentation is
available in the June of Well Formed for C# or VB programmers
http://www.bobpowell.net/currentissue.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

The GDI+ FAQ RSS feed: http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS: http://www.bobpowell.net/tipstricks.xml
Bob's Blog: http://bobpowelldotnet.blogspot.com/atom.xml






[quoted text, click to view]

Re: image graphics drawing confusion cwineman
7/30/2004 9:42:30 AM
I don't understand. I take an image, and write some ellipses on it. Fine.
Take that image and save it to disk and there it is with the ellipses drawn
on it. Good. Now, take the same image and create a thumbnail version of it.
Save it. Its a thumbnail, but there are no ellipses. Where did they go?

If there are two different buffers how do I know which ones are going to get
used in different method calls? The Save() method uses a buffer that has my
modifications, but the GetThumbnailImage() doesn't? How does that make
sense?

How do I "create your own thumbnail by drawing the image to a correctly
sized memory bitmap"? What methods do I use? Do you have a link to an
example maybe?

Thanks,
-cwineman


[quoted text, click to view]

Re: image graphics drawing confusion cwineman
7/30/2004 12:39:03 PM
Hmm. I'm not sure how it can have a pre-defined thumbnail. I dynamically
create a thumbnail of the size I desire. If there is a pre-difined
thumbnail, how large is it? Wouldn't it get over-written?

I've checked out your faq several times in trying to answer some of my
imaging questions. One thing you might consider adding is something about
how to load an image from a file buffer in memory. I had trouble with that,
and it seems like something that would be a pretty common need for
developers. I eventually had to use a bunch of COM calls (which I know
nothing about) to load from an IStream. The code is below. Is there some
easier way than that? Alot of people were saying I should write my own
IStream implementation. Seems like a lot of work just to load an image from
memory.

Thanks for you help.

Gdiplus::Bitmap * CSecurLinxImage::LoadBitmap( unsigned char * fileBuffer,
int length )

{

HGLOBAL m_hMem = GlobalAlloc( GMEM_FIXED, length );

BYTE* pmem = (BYTE*)GlobalLock(m_hMem);

memcpy( pmem, fileBuffer, length );

IStream* pstm;

CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);

Gdiplus::Bitmap * bitmap = Gdiplus::Bitmap::FromStream( pstm, FALSE );

GlobalUnlock( m_hMem );

pstm->Release();

return bitmap;

}


[quoted text, click to view]

Re: image graphics drawing confusion cwineman
7/30/2004 4:27:03 PM
I still don't get it. Maybe I'm dense.I don't see how (or why) one of these
image objects could (would) have a second buffer for storing a thumbnail
version of the original. What good would it do, since the thumbnail version
is really a modification of the original, to the width/height that the
caller wants?

Anyway, I rewrote my resizing function to look similar to the code you had
in your previous post. Now everything works just like a want.Thanks.

I guess maybe your FAQ is only for managed .NET. I have used the
System.IO.MemoryStream to create an image from a file buffer in memory. I
keep getting confused because I am writing imaging code using GDI+ in
managed and unmanaged code. What I was actually having problems with was
loading an image from a buffer in unmanaged C++. There is a function
Gdiplus::Bitmap::FromStream

And it requires an IStream. I couldn't find an equivalent of
System.IO.MemoryStream so I had to use all of those mysterious COM
functions. So I guess I should ask you, in unmanaged C++, do you know of a
better way to load a Bitmap from a file buffer in memory?

I appreciate you help. Have a good weekend.

[quoted text, click to view]

Re: image graphics drawing confusion cwineman
7/30/2004 4:37:19 PM
OK, a co-worker has explained something to me. I guess some jpg formats
store a thumbnail version of an image in their file structure. That is what
you were talking about.

Now, I don't think that explains what was going wrong. Even if I loaded my
System.Drawing.Image object using one of these thumbnail-encapsulating jpg
files, once it is loaded, it's independent of whatever file format it was
loaded from. The Image object just has a buffer for the original image data,
and wouldn't know about the thumbnail that may have been embeded in the jpg
file. Right? So the GetThumbnailImage() function would always dynamically
create a new image based on the original file content.



[quoted text, click to view]

Re: image graphics drawing confusion Bob Powell [MVP]
7/30/2004 5:39:59 PM
The GDI+ FAQ has articles on changing the resolution of an image and drawing
an image that will explain the process in more detail. Here's how to reduce
an image to 50% it's size...

Bitmap bm=Bitmap.FromFile("myImage.bmp");
Bitmap tmp=new Bitmap(bm.Width/2, bm.Height/2);
Graphics g=Graphics.FromImage(tmp);
g.DrawImage(bm,new
Rectangle(0,0,tmp.Width,tmp.Height),0,0,bm.Width,bm.Height,GraphicsUnit.Pixe
l);
g.Dispose();
bm.Dispose();
tmp.Save(......); // save the half-size file

Some JPEG images have a pre-defined thumbnail. This would have been
generated before you modified the image. I'm assuming that you changed the
bits for the main image, saved the thing, including the old thumbnail and
when you extract the thumbnail the software decides to use the old,
unchanged bits of the supplementary image, not the new ones.


--
Bob Powell [MVP]
Visual C#, System.Drawing

The Image Transition Library wraps up and LED style instrumentation is
available in the June of Well Formed for C# or VB programmers
http://www.bobpowell.net/currentissue.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

The GDI+ FAQ RSS feed: http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS: http://www.bobpowell.net/tipstricks.xml
Bob's Blog: http://bobpowelldotnet.blogspot.com/atom.xml






[quoted text, click to view]

Re: image graphics drawing confusion Bob Powell [MVP]
7/30/2004 9:24:51 PM
The point I'm trying to make is that if the original file had a thumbnail it
would be in a different part of the file structure and would look similar to
the original. Even though you changed the bits on the real image, maybe the
thumbnail bits didn't get changed. When you extracted the thumbnail again it
just gave you back the old, unaltered thumbnail stretched to whatever size
you asked for.

I will certainly put an article in there for loading an image from a file
buffer in memory. I did something like this a while ago for a customer who
had a bitmap in a byte buffer. I handed the byte buffer to a memory stream
and read the file in from the memory stream. That might work as an
alternative to your CreateStreamOnHGlobal method. You can construct a memory
stream with a byte buffer and hand the memory stream to the FromStream
method.
--
Bob Powell [MVP]
Visual C#, System.Drawing

The Image Transition Library wraps up and LED style instrumentation is
available in the June of Well Formed for C# or VB programmers
http://www.bobpowell.net/currentissue.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

The GDI+ FAQ RSS feed: http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS: http://www.bobpowell.net/tipstricks.xml
Bob's Blog: http://bobpowelldotnet.blogspot.com/atom.xml






[quoted text, click to view]

Re: image graphics drawing confusion Bob Powell [MVP]
7/31/2004 1:09:14 PM
The thumbnails are stored as PropertyItems associated with the image. I
think it's possible that the thumbnail property item could be saved out
again unchanged if it exists. Also, the GetThumbnail draws from the
thumbnail PropertyItem if it exists and does not necessarily construct the
thumbnail from the *real* image bits which is where I think your problem
arises.

--
Bob Powell [MVP]
Visual C#, System.Drawing

The Image Transition Library wraps up and LED style instrumentation is
available in the June of Well Formed for C# or VB programmers
http://www.bobpowell.net/currentissue.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

The GDI+ FAQ RSS feed: http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS: http://www.bobpowell.net/tipstricks.xml
Bob's Blog: http://bobpowelldotnet.blogspot.com/atom.xml






[quoted text, click to view]

Re: image graphics drawing confusion Bob Powell [MVP]
7/31/2004 1:14:46 PM
I actually haven't written any C++ for about 5 years... The FAQ does have a
bit of a managed code bias. Things will be changing on there very soon
though and C++ will always be an important language.

I will do something along those lines. To ensure that you see the articles I
suggest you subscribe to the RSS feed for the FAQ.

--
Bob Powell [MVP]
Visual C#, System.Drawing

The Image Transition Library wraps up and LED style instrumentation is
available in the June of Well Formed for C# or VB programmers
http://www.bobpowell.net/currentissue.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/gdiplus_faq.htm

The GDI+ FAQ RSS feed: http://www.bobpowell.net/faqfeed.xml
Windows Forms Tips and Tricks RSS: http://www.bobpowell.net/tipstricks.xml
Bob's Blog: http://bobpowelldotnet.blogspot.com/atom.xml






[quoted text, click to view]
AddThis Social Bookmark Button