Results 1 to 28 of 28

Thread: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Sometimes you need a better SavePicture() function. Not a lot better, just one that can save in some compressed format instead of just BMP format. Like JPEG usually, or PNG. Well this one does that, and throws in GIF as well though as usual (being based on GDI+) those tend to come out dithered and sort of crap in general.

    What we have here is a simple preclared-instance Class with one method: SavePicture().

    You give it a StdPiture, a file name (yes, it can save using Unicode paths), which format you want, and for JPEG you can add a "quality" in percent. It saves to disk, not to Byte arrays.

    Nothing here people haven't seen before. This is just a "stripped to essentials" rendition of the well worn theme.


    It only requires a version of Windows with IE 5 or later. It uses GDI+ but most systems with IE 5 or later cover that as well. In any case it should work on nearly anything you run anymore.

    There are no 3rd party DLLs required, and not even any typelibs. Just add PicSave.cls to your Projects.


    The attachment contains a simple demo. Its bulk is all source image data.


    The StdPicture you pass to it must have a bitmap handle. In practical terms this means you may have to pass it the persistant-image property (.Image) if you have drawn your picture onto a Form, PictureBox, etc. and there is no provision for dealing with metafile vector images.


    Notes:

    New attachment incorporating feedback from discussion below to address issues encountered when GDI v. 1.1 is in play, running on 64-bit Windows, etc.

    Also note that this makes no effort to handle transparency or alpha-channel translucency for GIF or PNG output. It saves simple "whole bitmap" images. If you load a picture with transparency into a StdPicture and save it back using this class the transparency is lost.
    Attached Files Attached Files
    Last edited by dilettante; Nov 1st, 2015 at 05:09 AM. Reason: replaced attachment

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    In response to a PM:

    No Ted, it is not using a WebBrowser control. I mentioned IE 5 because it makes a call to the Shell Lightweight Utility API and it requires Shell32.dll 5.0 or later, which in olden times was updated as part of IE.

  3. #3
    Fanatic Member
    Join Date
    Jan 2015
    Posts
    596

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Thanks, instructing and so light.
    I like the "photo of yourself"

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Couple things. Constructive criticism follows. You know I have respect for you, so don't take this in a negative way...

    1. Crashes when passing this line while picture contains GIF: PicSave.SavePicture Me.Picture "test.gif", fmtGIF

    2. GIF likely not to save with transparency if it has it, i.e., from a design-time loaded GIF. Same applies to PNG if trying to save GIF frame to PNG.

    Probably a good sample project, for learning purposes, for saving to JPG,PNG. GIF needs work.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Quote Originally Posted by LaVolpe View Post
    Couple things. Constructive criticism follows. You know I have respect for you, so don't take this in a negative way...
    I am far less concerned about reputation than about not misleading others with flawed code samples, so criticism is valuable.


    Quote Originally Posted by LaVolpe View Post
    1. Crashes when passing this line while picture contains GIF: PicSave.SavePicture Me.Picture "test.gif", fmtGIF
    I can't reproduce the problem. Can I assume "Me" is a Form? How was the GIF loaded into it?


    Quote Originally Posted by LaVolpe View Post
    2. GIF likely not to save with transparency if it has it, i.e., from a design-time loaded GIF. Same applies to PNG if trying to save GIF frame to PNG.
    I agree, but that wasn't the purpose here at all. Perhaps I should have stated that transparency is not addressed. I had things like webcam snapshots in mind when I cobbled this together.

  6. #6
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    I can't reproduce the problem. Can I assume "Me" is a Form? How was the GIF loaded into it?
    Well, seems doesn't really matter whether Me.Picture has a GIF or not, crash seems to occur. From catching it before/as it occurs, appears to be related to the SHCreateStreamOnFile call. If it doesn't crash after that call, then GdipSaveImageToStream always fails with a zero-byte gif file. Tested on Vista with all latest MS patches applied.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Hmmm...

    I tried this on Vista SP2, fully patched. Works fine, but 32-bit. Tried it on XP SP3, as fully patched as that can be anymore. Works fine, but 32-bit.

    Tried it on a 64-bit Windows Home Server 2011 box and it failed but created an empty GIF file. There seems to be some weird file-creation delay on 64-bit.

    No, stuffing in a DoEvents didn't help. Weird, weird, weird. I need to dig further because my entire point was to eliminate the need for any IStream typelib. Perhaps this just won't be practical.


    The error was a system error 2: ERROR_FILE_NOT_FOUND

    Did you get a different one?

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Something is fishy here because I see people using SHCreateStreamOnFile all over the place for all sorts of things.

    I'm beginning to wonder if this isn't a GDI+ v. 1.1 issue. Were you testing on Vista with a manifest selecting the v. 1.1 assembly? i don't have 64-bit Vista or 32-bit Win7 handy to test against.

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Ok. I dug up a 32-bit Win7 VM and sure enough it fails there the same way. I'm suspecting GDI+ v. 1.1 myself, but that doesn't really help much so I need to create a memory stream and write that to disk myself I suppose.

    GDI+: a snakepit!

  10. #10
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Sorry didn't get back to you sooner. Yes v1.1 via manifested IDE. Seems you've identified a bug

    You can still avoid the typelib by simply using GDIpSaveImageToFile

    After some trial & error, I got past the crashes this way.

    I changed all references in the class from "Object" to "IUknown". Don't know if that was absolutely necessary but it didn't immediately correct the problem, but it did get past the crashes that occurred on or immediately after calls to SHCreateStreamOnFile. Now the problem was the error related to GdipSaveImageToStream. GDI+ reporting invalid parameter.

    So I changed your GdipSaveImageToStream API declaration to pass the final parameter ByRef as Any. Then changed the call in your class to the following. Crashes & errors not occurring any longer.
    HRESULT = GdipSaveImageToStream(gdipBitmap, Stream, EncoderGUID, ByVal 0&)
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  11. #11

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Interesting.

    Ok, I changed the three As Object to As IUnknown though I'd assumed it shouldn't matter. I'm beginning to think that only matters under WOW64 but I'll live with it without further testing because the change costs nothing. Worth being aware of though so I'll make a note to myself for future reference... and now I wonder how much code I have with that potential time-bomb in it. *sigh*


    I decided to avoid the need to play flippity-flop having two separate calls to GdipSaveImageToStream.

    Instead I declared the last argument ByVal pEncoderParams As Long and have a pParams As Long that I either leave = 0 or assign VarPtr(Params) value to before the single call.


    Quote Originally Posted by The trick View Post
    I think need use GdipGetImageEncodersSize+GdipGetImageEncoders (ie GetEncoderClsid) for obtaining the Class Identifier for an Encoder.
    I'm not sure we need to do this here because I'm only making use of a subset of the encoders that both versions of GDI+ always come with. I suppose you could do that to retrieve all of the ImageCodecInfos and then build a mapping from a format-choice enum's values to those CLSIDs by parsing the MIME types. I'm not sure what value that has though.


    Thank you all for the valuable help.

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    BTW:

    Tested both versions on a Windows 95 OSR2 VM that has IE 5 installed. Both worked just fine there.

  14. #14
    Addicted Member
    Join Date
    Jun 2002
    Location
    Finland
    Posts
    169

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    You always say something like "It's crime to use Windows XP because ...(list of security issues)".
    And every now and then you say "This code also works with Windows 9x".
    Maybe it would be time to make a clearer alignment.

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Indeed, Windows XP is dead and no longer gets security updates and thus is dangerous for general use.

    That doesn't mean that an old versions of Windows might not be useful now and then for special cases, and sometimes you may not have a choice. Windows 95 through Windows XP are still often used as embedded system OSs. The vendor doesn't support installing another OS, or the systems are isolated from the Internet, the SOC board used has tiny RAM, etc.

    That is entirely different from a desktop or laptop being used as a general-purpose PC connected to the Internet for web surfing though.

  16. #16
    New Member
    Join Date
    Oct 2018
    Posts
    3

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    I just came across this post this evening and downloaded your module. It works fantastic! So, thank you very much!!

    I'm using VB 6 Pro under Windows 7 Home Premium 64 bit and having no troubles at all saving PNG images from my PictureBox controls. However, i did have one little issue that was very easy to overcome. The output file is 4 pixels smaller than the image control, both horizontally and vertically. So, all i did was add 4 pixels to height and width to get the image output size i want.

    Thanks again!

  17. #17

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    I'm not sure about those 4 pixels. Is there a High DPI scenario in play that is throwing calculations off a bit? Or are you trying to save the borders of the Image control?

    Here's a newer version with loading and saving, just the .CLS file.
    Attached Files Attached Files

  18. #18
    New Member
    Join Date
    Oct 2018
    Posts
    3

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Quote Originally Posted by dilettante View Post
    I'm not sure about those 4 pixels. Is there a High DPI scenario in play that is throwing calculations off a bit? Or are you trying to save the borders of the Image control?

    Here's a newer version with loading and saving, just the .CLS file.
    I did figure it out. Total goof on my part. I was using .height & .width instead of .scaleheight & .scalewidth.

    Thanks for the new version! Will try it out. Being able to load too will be a big help.

    - k

  19. #19
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,121

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    @dilletante: JFYI, possible to skip the GdipImageRotateFlip call if using negative height in BITMAPINFO.bmiHeader.biHeight = -.bmHeight

    Not tested extensively besides saving to a PNG but it seems you are not dealing with vbPicTypeIcon's or any other non-picture type so probably is good enough.

    cheers,
    </wqw>

  20. #20
    New Member
    Join Date
    Oct 2018
    Posts
    3

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    I have created my own picture types, using a longint array, and all my own drawing routines that allow ultra-hires 16384x9216 in some projects. The routines allow anti-aliased drawing, transparency, and a host of plotting permutations like lighten, darken, invert, etc. All the goodies an artist needs that aren't included in VB. However, i then copy the image buffer over to a standard VB picture box for saving, so your save to PNG routine works perfectly. Thanks again!

  21. #21

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Quote Originally Posted by wqweto View Post
    @dilletante: JFYI, possible to skip the GdipImageRotateFlip call if using negative height in BITMAPINFO.bmiHeader.biHeight = -.bmHeight
    Excellent point. Seems so obvious now.

    Quote Originally Posted by wqweto View Post
    Not tested extensively besides saving to a PNG but it seems you are not dealing with vbPicTypeIcon's or any other non-picture type so probably is good enough.
    That's true. I should probably be more explicit that only bitmap type StdPicture objects are supported and not icon, metafile, etc. as well as test for other types and throw an exception for that.

  22. #22
    Member
    Join Date
    Oct 2019
    Posts
    37

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Hi,

    Dilettante, I would like to have your permission to use your code for my Vb81 emulator; posted here.

    Name:  vbforum.JPG
Views: 5817
Size:  48.8 KB

    Project web location: http://zx81.vb81.free.fr

    [edit] Thanks for help Dilletante, the project is now updated. It's a VB5 release but your code seem working properly. (note: the res file isn't update. a link to this page is enclosed in the binary zipped file)

    If something's wrong, let me know.
    Last edited by XavSnap; Oct 3rd, 2019 at 04:55 PM.

  23. #23
    Addicted Member
    Join Date
    Jan 2010
    Posts
    250

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    amazing..i am using this class for my app for saving photo..really great, and simple

  24. #24

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Looks like I had missed a post above. In any case feel free to make any use of the code you wish. Just glad to have been of help.

  25. #25
    Lively Member
    Join Date
    Jan 2009
    Location
    Mn-USA
    Posts
    124

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    This code works very well. But can it be enhanced to convert to SVG files?
    There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!
    Richard P. Feynman

  26. #26

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    I suppose it could, but it wouldn't be what you want. Just a wrapper SVG around a non-scaleable bitmap.

    I you really want vector graphics you must at least begin with a vector graphics format to convert from. Or forget about SVG and use EMF/WMF formats.

    There is no native support for SVG in Windows except perhaps in later versions of Direct2D.

  27. #27
    New Member
    Join Date
    Oct 2020
    Posts
    1

    Thumbs up Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    Quote Originally Posted by dilettante View Post
    I'm not sure about those 4 pixels. Is there a High DPI scenario in play that is throwing calculations off a bit? Or are you trying to save the borders of the Image control?

    Here's a newer version with loading and saving, just the .CLS file.

    Thank you so much Friend !
    It solved my very important problem to save Base64 QR Code to a BMP file.
    Thank you so much !!

  28. #28
    Fanatic Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    784

    Re: [VB6] PicSave - Simple SavePicture as GIF, PNG, JPEG

    dilettante,

    Thank you for this class, if I can just learn to use it properly.

    I have compiled a picture named picCompiled from many different maps as in:

    Code:
    On Error GoTo NoPicture
    Dim PictureAndPathname As String, PictureName As String
    pb.Value = 0
    fraProgress.Visible = True
    For i = 17 To 25
        pb.Value = (i - 17) * 12
        For j = 31 To 25 Step -1
            PictureAndPathname = App.Path & "\Google Maps\Google " & CStr(i) & "-" & CStr(j) & ".jpg"
            PictureName = "Google " & CStr(i) & "-" & CStr(j) & ".jpg"
            picTemp.Picture = LoadPicture(PictureAndPathname)
            picCompiled.PaintPicture picTemp, i, j, 1.001, -1.001
    10    Next j
    Next i
    fraProgress.Visible = False
    On Error GoTo 0
    I can see that it is properly compiled when I look at the picturebox.

    And I use this to save it with:

    Code:
    PicSave.SavePicture picCompiled.Image, "C:\OneDrive\My Programs\Google Maps\picCompiled.jpg", fmtJPEG, 70
    The file appears in my explorer.
    It should be 11 MB, but it is 60 kB and when I open it with paint, it is blank.

    What could be the cause of that?

    Thanks
    PK

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width