If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

This code also works fine, and shows a PNG file in a picturebox.
However, when I use that resize piece of code to resize the PNG image to fit the picturebox, it gives me a runtime error:
Run-time error 481: Invalid picture.

I am really looking for a minimallistic way of doing it.
I don't think I'd be comfortable with subclassing or very complicated approaches. I have never done subclassing before.
Hopefully there is an easy way of resizing a PNG image.

Re: Runtime error when trying to resize a PNG picture

Is the value of Picture1.Picture zero? When you draw onto a picturebox, you are not drawing into the Picture property. Drawing has no effect on the picture property. If there wasn't a picture handle there before, there isn't one afterwards.

1. Make the picturebox AutoRedraw = True
2. Resize the picturebox before drawing, to the size you want the "picture" to be
3. Cls before drawing then draw on it at the same size as your picturebox
4. Then: Set Picture1.Picture = Picture1.Image. That set's the picture property
5. You can remove AutoRedraw if desired

P.S. The GdipDrawImage will render the picture using any embedded DPI settings within the PNG. And last but not least, when you start GDI+, you still need to terminate it. You rem'd out the GdiplusShutdown call -- it needs to be called once for each Token you create from GdiplusStartup

All of the above said, I think you simply used the wrong GDI+ function for drawing. GdipDrawImage can only draw full scale. GdiplusDrawRectIRectI is more like PaintPicture/StretchBlt you could have used that instead, within your RenderPNG function. The example, you used & quoted me, was likely from a post where actual size was wanted.

Edited: Once saved into a VB picture object, transparency is permanently lost. Minimalist code is not always the best code.

The easiest way (on Vista or better) to draw a PNG actual size, to include any, transparency, is to load the PNG as an Icon into a stdPicture object (via a few APIs). Then use DrawIconEx API to render it wherever you need. That option only applies to PNGs. Note that I mentioned actual size... scaling icons other than actual size produces less than desirable results in most cases.

There are many ways today, that we can merge GDI+ with VB picture objects. But the solutions are usually heavy code contained in usercontrols or classes. If you don't mind trying a class, here is one in the code bank. If you don't like it, just remove it. Using that class, your example simplifies to this:

Re: Runtime error when trying to resize a PNG picture

Originally Posted by LaVolpe

...
There are many ways today, that we can merge GDI+ with VB picture objects. But the solutions are usually heavy code contained in usercontrols or classes. If you don't mind trying a class, here is one in the code bank. If you don't like it, just remove it. Using that class, your example simplifies to this:

There is just one small problem left to resolve, and that is obviously my own fault that I didn't mention in the first post.
In the first post I said that I wanted to size the PNG picture to a picturebox.
However, I can now see that doing so, stretches the image and distorts the aspect ratio.

The code that you provided certainly did what I asked for. But it also stretched the image to fit into the picturebox.
But I mistakenly asked for something wrong.
Actually, the aspect ratio needs to be preserved.

So, I need to do this:

Appraoch 1:

show a PNG file into a picturebox, so that it fits perfectly into the picturebox width-wise.
Then the Picturebox's height needs to be changed to fit the image.

Appraoch 2:

Alternatively, another thing to do instead would be to show a PNG file into a picturebox, so that it fits perfectly into the picturebox height-wise.
Then the Picturebox's width needs to be changed to fit the image.

Edited: When you are doing this, keep in mind scalemodes. Don't mix apples and oranges. Best to convert target/image dimensions to same scale, be it pixels, twips, whatever. And when using PaintPictureEx, same rules apply when using VB's PaintPicture -- rendering dimensions & offsets are in the target's scalemode. Please read the comments in the class' PaintPictureEx routine.

P.S. The class does have a function to return the dimensions of any stdPicture object: GetImageDimensions. The dimensions are returned in pixels and the function is DPI-aware.

Re: Runtime error when trying to resize a PNG picture

After re-reading your previous reply, sounds like I misunderstood.

The pseudo code I gave calculates the scale ratio to maintain original aspect - ok. But it sounds like you want to resize the picturebox based on scaled ratios? If so, the pseudo code gives you the best fit scale ratio and you won't be worrying about centering. You will then need to resize your picturebox to the calculated scaled dimensions - understand?

A problem I see with that logic is that you can't really be adding new images to the picturebox time and time again. If so, then you will consistently be reducing the size of that picturebox each time a new picture scaled and rendered to it, unless the pictures all happen to be the same original size. If this scenario applies, you will want to have a 'reset logic' that starts with a default picturebox size that is constant.

Another tip for the ratio scaling logic... I often find cases where I want scaling down only, not scaling up. In other words, keep 1:1 aspect unless image must be scaled down to fit, but never scale up. If you also have a need for that, you would add one more IF statement to your scaling logic...

Re: Runtime error when trying to resize a PNG picture

Thanks for your help.
Actually, I am trying to develop something similar to Windows Explorer, but one that is completely part and parcel of a VB application, so that the user can double-click on a file's thumbnail to invoke a certain process.

Lets first see how Windows Explorer shows thumbnails:
It considers one imaginary square for each image, and then it uses the Approach 1 (if the image is landscape style) or Approach 2 (if the image is portrait style) that I explained in Post #3 above.
This screenprint shows that logic:https://i.imgur.com/gnZrpSm.jpg

It fits the image perfectly into my square-shaped Picturebox, but by doing so, it stretches (distorts) the image into becoming a perfect square.
For example, my image is this:https://i.imgur.com/NkoGl98.png

When I BEGIN with a square-shaped PictureBox, and try to fit an image (contents of a PNG file) into it, the borders of that initial Picturebox are supposed to act as limits that the resize logic must not EXCEED.
What it means is that when I begin with a square-shaped PictureBox, I need to establish this logic:

If the image in a PNG file is landscape-style Then (Appraoch 1):

Show a PNG file into a picturebox, so that it fits perfectly into the picturebox width-wise.
Then the Picturebox's height needs to be changed to fit the image.

ElseIf the image in a PNG file is portrait-style Then (Appraoch 2):

Show a PNG file into a picturebox, so that it fits perfectly into the picturebox height-wise.
Then the Picturebox's width needs to be changed to fit the image.

I changed PaintPictureEx call to use the picturebox .hDC property. If you look at that method in the class, it is more efficient to pass an hDC then to pass an object. If passing hDC, the only strict rule is that all parameters are in pixel scalemode -- which we take care of above.

Re: Runtime error when trying to resize a PNG picture

Thanks.
I implemented this approach and there are three issues in here:

A. The function ScaleToDest in post#5 has an End Sub" in the end. It doesn't compile.
But, I changed that to "End Function" and the problem is fixed.

B. This line (in post #7):

Code:

cStdPicEx.PaintPictureEx Destination, Source.hDC, X, Y, Cx, Cy

gives me this error:
Error #438: Object doesn't support this property or method

I changed it to:

Code:

cStdPicEx.PaintPictureEx Destination, Source, X, Y, Cx, Cy

And it looks like this problem is fixed.
Not sure though.
Can this change cause any problems under other circumstances?

C. Your code properly does the first step: It resizes the contents of a PNG file to fit the Picturebox.
But it does not do the second step that is the final stage of resizing the PictureBox to fit the re-sized image.
For example in this screenshot:https://i.imgur.com/t8Kszsq.jpg

I guessed I could do that by adding the following code that you had provided under a different thread:

Re: Runtime error when trying to resize a PNG picture

1. The "End Sub" vs "End Function" was just a typo when I wrote the code in the reply section

2. "Error #438" another typo -- think my age is catching up to me. That line should've been following, the destination has hDC property

Code:

cStdPicEx.PaintPictureEx Destination.hDC, Source, X, Y, Cx, Cy

3. I kinda figured, you know how to resize picturebox. And frankly, don't understand why it's necessary. If you are creating something like a grid, why not just make the picturebox borderless with a solid background color the same as its container?

Re: Runtime error when trying to resize a PNG picture

Originally Posted by LaVolpe

A few things:

1. ...
2. ...
3. I kinda figured, you know how to resize picturebox. And frankly, don't understand why it's necessary. If you are creating something like a grid, why not just make the picturebox borderless with a solid background color the same as its container?

Thanks a lot for the response.
You are probably right.
But, I just can't believe why there is no way on earth to obtain the width and height of an image displayed in a picturebox.
If there is an image, there should be one way to obtain its width and height.
But nothing gives me those sizes (width and height)
For example the following:

Code:

PicBox.Image.Height
PicBox.Image.Width

do not give me those numbers
So, what kind of code gives me those numbers?

Also, back to the main thing:
Even though your suggestion is good and valid, I still need to resize that picturebox.
I don't know how to do it.
can you please help?

Re: Runtime error when trying to resize a PNG picture

Any help on this issue would be greatly appreciated.

What I want to do consists of two steps: (the first step is already done):

Step 1: I have managed to resize a picture (contents of a Png or Jpg, etc. file) to fit perfectly within the borders of a Picurebox.
I have managed to do so, with great help from LaVolpe (Many thanks to him).

Step 2: Now, the second step is to resize the Picturebox itself to fit the image that it displays in order to remove the two strips of empty space to the sides of the image inside the Picturebox.

Re: Runtime error when trying to resize a PNG picture

I still suggest you do not resize the picturebox. What happens when you add a different picture later? Now the picturebox is smaller than it was and the the new picture is resized smaller than it should be. Then you resize the picutrebox again. Keep doing this and eventually your picturebox size nears 0 x 0. Instead, recommend making the picturebox borderless and same backcolor as your form

To resize it, if it is not in a frame and the form or picturebox scalemode is not User-defined...

Re: Runtime error when trying to resize a PNG picture

Thanks for the help.
There are two small issues left to resolve:

1. There is a rare situation when the picture in question is very tiny (for example a logo or an icon).
In that case, resizing the picture to make it fit the picturebox means magnifying it (instead of shrinking it). The code that you provided, magnifies a tiny icon to make it fit the picturebox.
In that case, I need to show the picture without resizing it.
In other words, if the image's both dimensions are smaller than the picturebox, I want to do the opposite (resize the picturebox to fit the image).
In order to do that I add the red part to the code below:

And it works perfectly.
But, as you see in the red code above, I compare tpicPNG's height or width with the picturebox's height or width directly (without any scaling or conversion ratio) and it works.
I thought a conversion ratio was needed.
Isn't it strange?
Isn't a conversion ratio needed?

2. In post #2 above, you have done this declaration at form level (outside of Command1_Click):

Code:

Dim tpicPNG As StdPicture

In my code, when I do that declaraion locally (inside Command1_Click), it works perfectly.
Is there any good reason to declare it at form level?

Re: Runtime error when trying to resize a PNG picture

Regarding magnifying (scaling up vs down), the routine I gave you in post #5 has a parameter to prevent that. Try it.

Regarding declaring tPicPNG in the declarations section... You only need to do that if that variable will be used by more than one procedure in your form. If it will only be used in Command1_Click, then declare it there.

Re: Runtime error when trying to resize a PNG picture

Originally Posted by LaVolpe

Regarding magnifying (scaling up vs down), the routine I gave you in post #5 has a parameter to prevent that. Try it.

Regarding declaring tPicPNG in the declarations section... You only need to do that if that variable will be used by more than one procedure in your form. If it will only be used in Command1_Click, then declare it there.

Thanks a lot.

I just used the Canscaleup parameter and it works excellently for me.
Though, I am just curious about the conversion ratio.
Am I correct in saying that tpicPNG.Height and MyPictureBox.Height can be compared without any conversion ratio (the conversion ratio being 1)?
For example:

Code:

If tpicPNG.Height < MyPictureBox.Height Then ......

If the conversion ratio is not 1 (I think it is), then what is the conversion ratio?

Regarding declaring tPicPNG: If I declare tpicPNG inside a procedure that displays one picture to fit one picturebox, and then I call that procedure hundreds of times in a loop, could that cause any excessive memory use, or memory fragmentation or any similar issues?
In this specific case (a procedure that displays one picture to fit one picturebox) what is the best place to declare tpicPNG?

Same question about

Code:

Dim cStdPicEx As stdPicEx2

If I declare this inside a procedure that displays one picture to fit one picturebox, and then I call that procedure hundreds of times in a loop, could that cause any excessive memory use, or memory fragmentation or any similar issues?

Re: Runtime error when trying to resize a PNG picture

Your first question -- the answer is no and should have been able to prove that. Picture (images) dimensions are in himetrics. Picturebox dimensions are not.

Your second question about tPicPng. I already tried to explain that to you. If you need to reference the variable in more than one routine in your form, then declare it in the declarations section. Otherwise, declare it in the routine it is used in. The same does for any declaration, including "Dim cStdPicEx As stdPicEx2"

Advertiser Disclosure:
Some of the products that appear on this site are from companies from which QuinStreet receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. QuinStreet does not include all companies or all types of products available in the marketplace.