SAving bitmap file as Jpeg or GIF using MSPAINT

SAving bitmap file as Jpeg or GIF using MSPAINT

To answer a query in a previous post, here is how open MSPAINT from my application to display a bitmap (hidden) andutilise MSPAINT's Save As dialog to save it as a jpeg. You can also save it as a Gif.

Code:

use dfwinty
TYPE (T_SHELLEXECUTEINFO) SHINFO
character($maxpath)	::  bitmapfile, windir, paintdir
integer*4 ret, ghWnd, hPaint, hPaintMenu, hPaintMenu1, hPaintMenuitem
logical retlog


! Find the windows directory, stored in environment variable "WINDIR"
! Could also use "SystemRoot" environment variable
LENGDIR=GETENVQQ("WINDIR", WINDIR)
! MSPaint is usually in the system32 sub-folder
PAINTDIR=WINDIR(1:LENGDIR)//'\system32\mspaint.exe'C

SHINFO%cbSize=		sizeof(SHINFO)
SHINFO%Fmask=		SEE_MASK_NOCLOSEPROCESS 
SHINFO%hwnd=		ghWnd
SHINFO%lpVerb=		loc('open'c)
SHINFO%lpFile=		loc(PAINTDIR)
SHINFO%lpParameters=loc('"'//bitmapfile//'"'c )
SHINFO%lpDirectory=	loc('C:'C)
SHINFO%nShow=		SW_HIDE

retlog=ShellExecuteEx(SHINFO)
if(SHINFO%hInstapp.lt.32) then
	ret=MESSAGEBOX(ghWnd,'Failed to find//launch MSPaint'C, &
	'Problem saving the plot as JPEG file using MSPaint'C, &
	MB_ICONEXCLAMATION .OR. MB_OK)
			
	MainWndProc=0
	return
endif

! minimise this application's window so MSPaint's 'Save As' dialog can be seen
ret=SendMessage(ghWnd,WM_SYSCOMMAND, SC_MINIMIZE,0 ) 
call sleepqq(1000)   ! give program time to load
hPaint=FindWindow_g1('MSPaintApp'c, NULL )  ! Get the handle to MSPaint window
hPaintMenu=GetMenu(hPaint)					! Get the handle to the main menu
hPaintMenu1=GetSubMenu(hPaintMenu,0)		! Get the handle to the first drop-down menu
! Get the handle to the 4th (zero-based) item in the drop-down menu
hPaintMenuItem=GetMenuItemId(hPaintMenu1,3)	
! Send a command that this menu item has been selected...this should launch the 'Save As' dialog
ret=SendMessage(hPaint,WM_COMMAND, MAKEWPARAM(hPaintMenuItem,0), NULL)

! wait for display of Save As dialog and waste time in the loop
! for as long as the 'Save As' dialog exists...
call sleepqq(1000) 
  
do while(FindWindow_g1('#32770(Dialog)'c, 'Save As' ).ne.NULL)
end do
call sleepqq(1000) ! make sure data is saved before sending command to exit MSPaint... 
   
ret=SendMessage(hPaint,WM_CLOSE, 0, 0 )	! close MSPaint after 'Save As' dialog is completed
ret=SendMessage(ghWnd,WM_SYSCOMMAND, SC_RESTORE,0 )	! Restore application's window
retlog=SYSTEMQQ('DEL '//bitmapfile) ! Delete unwanted bitmap file, if desired
14 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

P.S. I use Compaq Visual Fortran 6.6C and W2K.
1) Use of FindWindow_G1 requires USE USER32. It is a wrapper for
the Windows API function FindWindow
2) The arguments usedby FindWindow_G1 were establishedby first
starting MSPAINT and clicking on File..SAve As to open the 'save as'
dialog and then startingthe Microsoft utility SPYXX.EXE and using the
'Spy..Find Window' menu item to discover the class names of the main
MSPAINT window and the dialog box.SPYXX.EXE comes with developer
studiowith CVF and should be automatically installedin a /common/tools/
sub-folder. It is very useful for studying window handles, messages etc.

Very inspiring. Could you please elaborate more on the specific command(s) needed to send the JPG FileID to,
and then close the "save as" dialog.
Greg

Um, a standard 'Save As' dialog box appearsso you just use it: navigate to the directory of your choice, enter the filename of your choice and click on the 'OK' button, AFTER having selected 'Jpeg' in the 'Save as Type' list box. The bitmapfile name appears as the default selection, and the application's directory is selected by default, so it is quite possible, if you wish to accept these choices beforehand, to send a message to the diaolg box to'click' on the 'OK' button and exit - but it will also be necessary to send a message to the 'save as type' list box to select 'Jpeg' before doing this. It is quite possible to automate this, so long as MSpaint's menus and the position of the Jpeg file selection in the list box remains fixed.

P.S. My sample code was obviously for an interactive application, where the user is required to make a choice. If you want a batch-type solution, then obviously more work is needed, as my final sentence indicates.

Message Edited by anthonyrichards on 06-27-2005 02:24 AM

Anthony,

Thanks for posting the code. I can now save my file as jpg or gif when prompted. However, I would really like it to automatically save it as jpg as Greg requested.

Good thing is if in saveimage command I deliberately give the saved image name a jpg extension (even though it is a bitmap) the save as dialog box of mspaint has the the jpg file type already selected. Now All I want to do is click the ok button and did a WM_KEYDOWN. That however did not save the image into the lower size jpg file, even though it did not give it an error.
Any thoughts how to automate this would be really appreciated.
Thanks

Sumit

Here is dialog application with 4 buttons:
to launch MSPAINT with a (coded in) user-supplied bitmap file
and open the common dialog 'save as' dialog box
to search through the 'Save As' dialog box controls for the 'Save As'
combobox and the 'Save' button
to close MSPAINT'
to exit the application

Informative message boxes are put up as you cycle through the controls in the 'SAVE As' dialog. Just keep pressing on the 'OK' button in the message box.

When you see how it works, you can extract the code you want to use.
It is worth changing the ShellExecute information conmponent to alternately 'SW_MINIMIZE' and 'SW_HIDE' to see the differences in behaviour. I guess you want to prevent both the MSPAINT and its 'Save As' dialog appearing.

In order to avoid a prompt dialog appearing, that requires user-input, you should ensure beforehand that the filename (with extension) that you have chosen to save is unique.

I should have added that the code looks for 'jpeg' within the 'Save As' combo box drop-down list, selects it, then, after finding the 'Save' button, presses it to save the MSPAINT-displayed bitmap asa jpeg file with jpg extension. WIth knowledge of the various filetypes in the drop-down list, it is possible to program the selection of any of the file types in the same way as is demonstrated with the Jpeg-type.

Hello,

i have used the shown source code to use mspaint to save bitmaps (jpg, png) since a long time. We have changed our operating system towards Win 7 Prof 64 bit. Now the shown source code is not working.

I do use the following source code:

    LENGDIR=GETENVQQ("WINDIR", WINDIR)
    ! MSPaint is usually in the system32 sub-folder
    PAINTDIR=WINDIR(1:LENGDIR)//'system32mspaint.exe'C
    ! ShellExecute Parameter definieren
    SHINFO%cbSize=        sizeof(SHINFO)
    SHINFO%Fmask=        SEE_MASK_NOCLOSEPROCESS 
    !SHINFO%hwnd=        xWnd
    SHINFO%lpVerb=        loc('open'c)
    SHINFO%lpFile=        loc(PAINTDIR)
    SHINFO%lpParameters=loc(bitmapfile )
    SHINFO%lpDirectory=    loc('C:'C)
    SHINFO%nShow=        SW_HIDE
    ! MsPaint starten
    bSt=ShellExecuteEx(SHINFO)
    call sleepqq(500)
    ghPaint=FindWindow_g1('MSPaintApp'c, NULL )  ! Get the handle to MSPaint window
    hPaintMenu=GetMenu(ghPaint)                    ! Get the handle to the main menu
    hPaintMenu1=GetSubMenu(hPaintMenu,0)        ! Get the handle to the first drop-down menu
    i = SetCursor(hSaveCursor)   !/* Restores previous cursor */
    ! ####################################
    ! Get the handle to the 4th (zero-based) item in the drop-down menu
    hPaintMenuItem=GetMenuItemId(hPaintMenu1,3)    
    ! ####################################
    ! Send a command that this menu item has been selected...this should launch the 'Save As' dialog
    ! Use 'PostMessage' to prevent locking up of this dialog waiting for return from MSPAINT...
    iSt=PostMessage(ghPaint,WM_COMMAND, MAKEWPARAM(hPaintMenuItem,0), NULL)
    call sleepqq(500) 

Does anyone had the same problem? Any solution?

Thanks in advance

Frank

For help, we need to know where the program falls over now. Please enlighten us.

Hello,

in the old days the program mspaint has been startet in the background. The 'save_as' dialog was shown.

Now there is no mspaint in the taskmanager and no 'save_as' dialog.

Thanks in advance
Frank

Anthony,

Why use Paint? Wouldn't it be easier, and less prone to future problems (no Paint), if you incorporate a JPEG compression/decompression library that should be available on sourceforge.net (e.g. http://gnuwin32.sourceforge.net/packages/jpeg.htm)

Jim Dempsey

www.quickthreadprogramming.com

JIM,
37 lines of FORTRAN code, excluding comments, IS pretty easy I think. I agree it all falls over when MSPAINT is no longer issued. If the menu options change, or window class names change, those problems should be 'easily' dealt with. I just thought, why not use code that exists to do the job, especially as MSPAINT offers so many image formats for free.

I would like to know if MSPAINT exists on the poster's system? If it does, perhaps it is a problem with window class id's or menu options. If not, then that's that and a freeware solution is required (for those of us not into image processing at the nuts and bolts level).

For further diagnostics, I think it would be wise to add and activate some MessageBox messages at certain stages through the calling code to gve information about return codes etc as the program code executes.

I have been hesitating about responding to this thread, after all tropfen has been around here for some time so should know the usual respones (run in debug mode; check return values/flags; switchall runtime checks on,etc)
The only thought I had was whether the handles were still integer(4) or whether they should be integer(HANDLE) on the Win7 64 bit system. I'm pretty sure mspaint.exeexists on my Win 7 laptop (in c:\windows\system32) but I haven't been able to run the given code on it yet.

$0.02
Les

>>37 lines of FORTRAN code, excluding comments, IS pretty easy I think

With the proper library this may be one line of code, and you will never have to changethe programwhen:

MSPAINT goes away
MSPAINT is given a new face (drop down menues change)
parlez-vous franais
...

To protect against this .AND. use MSPAINT, I would suggest the user writes the internal format to file as-is, then calls an external program, preferably a script file, that performs the conversion file to file (optionally deleting input file too). The initial conversion program can be MSPAINT or other convient tool. Later if MSPAINT changes or your requirements change. you simply change thescript file to use that other program/utility/library.In this way, the compiled FORTRAN program need never to be updated (with regard to format exchange).A conversion utilityprogram will likely be much smaller than MSPAINT, so the overhead to write the temp file will be returned by the lower load time of the conversion program.

Finding an appropriate library and integrating it into y0ur application may take a few hours of web searching. You will have to be the judge as to how many hours this will save you (or the next person supporting the program) in the future.

Jim Dempsey

www.quickthreadprogramming.com

Leave a Comment

Please sign in to add a comment. Not a member? Join today