Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Compressing Image files 2

Status
Not open for further replies.

vj

Programmer
Nov 18, 2000
58
MU
hi guys,

i'v got a Nikon D5300 camera and have connected it to the pc .. in my form iam using ShellExecute to run a .exe file that clicks the photo and saves it in a path .. and displays it on the image control on my form .. it is all fine upto here .... but now since the file size is very big ... i need to compress this image ... can anyone suggest any simple software that would compress the image into a predefined dimension and picture quality ... so the user does not have select or configure anything.

thankx alot
vijay
 
ImageMagick should be able to do this. It's a command-line utility, which means you can call it from ShellExecute(), passing command-line parameters. See
I suspect that what you really want to do is to resize the image rather than compress it. Most modern digital cameras take photos at a much higher resolution than you really need. By reducing the size of the image (say from 2816 x 2112 to 800 x 600), you can make a substantial saving in the size of the file, without any noticeable loss in quality.

In addition, in the case of JPGs, you can opt to save the image at a lower quality. Reducing the quality from, say 100% to 70%, youi will get a big saving in file size, and in most cases the image will look just as good.

ImageMagick should be able to handle these conversions.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
You could also use a VFPX project gdiplusX to resample the images in sizes better fitting a screen than the HD resolutions you get from a camera.
I've done an batch image shrink routine reducing pictures to some percentage or a fixed width or height (whatever is larger) reducing the other dimension keeping the original aspect ratio.

Once you have the gdiplusx system.app, this is working along this sample code:
Bye, Olaf.
 
mike ... i'v downloaded and installed the imagemagic ... this is what i do to click the photo
DECLARE INTEGER ShellExecute IN shell32.DLL ;
INTEGER hndWin, ;
STRING cAction, ;
STRING cFileName, ;
STRING cParams, ;
STRING cDir, ;
INTEGER nShowWin

CACTION = "open"
CFILENAME='c:\Item-Photos\Others\NKRemoteLibTest.EXE'

SHELLEXECUTE(0,CACTION,CFILENAME,"","",1)

should i follow the same for the Image Magick ... or some other syntax...

it's a bit confusing ...

thankx
vijay

 
Vijay,

That's nearly correct, but not quite. You need to pass the command-line parameters as the 4th parameter (cParams) to ShellExecute().

So, for example, these are the command-line parameters to convert MyImage.jpg to MySmallImage.jpg, with a size reduction of 50%:

Code:
MyImage.jpg -resize 50% MySmllImage.jpg

And to pass that string to ShellExecute:

Code:
cParams = "MyImage.jpg -resize 50% MySmllImage.jpg"
cFileName = "convert.exe"   && add the path to convert.exe if necessary
cAction = "run"
SHELLEXECUTE(0,CACTION,CFILENAME,"","",1)

But before you go any further, you should read the documentation for ImageMagick. It will tell you far more about how to use it than I can.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Code:
FUNCTION Thumbnail(tcFile,tnW,tnH)
	
		LOCAL img,IP, lcFile
		IF EMPTY(tcFile)
			RETURN 
		ENDIF 
		lcThumbFile = ""
		TRY
			img = CREATEOBJECT("WIA.ImageFile")
			IP = CREATEOBJECT("WIA.ImageProcess")
			lcFile = tcFile
			IF EMPTY(lcFile)
				lcThumbFile = ""
				EXIT
			ENDIF

			IF PCOUNT() = 1
				lcImgHeight = 140
				lcImgWidth = 140
			ENDIF 
			IF TYPE("tnW") = "N"
				IF tnW > 0
					lcImgWidth = tnW
				ENDIF 
			ENDIF
			
			IF TYPE("tnH") = "N"
				IF tnH > 0
					lcImgHeight = tnH
				ENDIF 
			ENDIF 
*			SET STEP ON 
			lcFile = '\EzResizer\Images\'+lcFile 
			img.LoadFile(lcFile)
		
		
			IP.Filters.ADD(IP.FilterInfos("Scale").FilterID)
			IP.Filters(1).Properties("MaximumWidth") = lcImgWidth
			IP.Filters(1).Properties("MaximumHeight") = lcImgHeight
			img = IP.APPLY(img)
			lcThumbFile = JUSTSTEM(ALLTRIM(lcFile)) + ".bmp"
			lcThumbFile =   "\EzResizer\Thumbnail\" + lcThumbFile
			IF FILE(lcThumbFile)
				ERASE (lcThumbFile)
			ENDIF
			img.SaveFile(lcThumbFile)


			Img = CreateObject("WIA.ImageFile")
			IP = CreateObject("WIA.ImageProcess")
			Img.LoadFile( lcThumbFile)
			IP.Filters.Add( IP.FilterInfos("Convert").FilterID)
			IP.Filters(1).Properties("FormatID").Value = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}" && JPG format
			IP.Filters(1).Properties("Quality").Value = 100
			Img = IP.Apply(Img)
			lcJpgFile = JUSTSTEM(ALLTRIM(lcThumbFile)) + ".jpg"
			lcJpgFile = "\EzResizer\Thumbnail\" + lcJpgFile
			IF FILE(lcJpgFile)
				ERASE (lcJpgFile)
			ENDIF 
			Img.SaveFile( lcJpgFile)
			
			RELEASE Img
			RELEASE IP
			ERASE (lcThumbFile)

			EXIT
		CATCH TO loExp
			MESSAGEBOX("There was an error converting image to thumbnail.  Please try again."+CHR(13) + ;
				"Error: " + loExp.MESSAGE + CHR(13) + ;
				"Line No: " + TRANSFORM(loExp.LINENO),16,"Thumbnail generator")
			lcThumbFile = ""
			EXIT
		ENDTRY

		RETURN lcThumbFile
	ENDFUNC

Ez Logic
Michigan
 
Olaf

thankx alot for that info page .. it is great ... i'v used the sample 3 - CUSTOMIZED RESIZING from page -
it works perfectly fine , but i was wondering if there is a way to extract a part of image and then save that part as a new image . for e.g. if there is a image - 3000X2000 dimension and i want to select a part 1500X1000 from the center of that big image and save as a new image file .... is that possible ... is there sample demonstrating that capability ??

thankx
vijay
 
though i am a newbie, i learn to use this image compression toolkit to compress all kinds of image, it is simple and easy to manipulate. all you need to do is follow the tutorial and then you will how to compress quickly.
 
Hi vijay,


The essential part is

Code:
DO LOCFILE("System.App")
WITH _SCREEN.SYSTEM.drawing
        m.lobmp	   = .BITMAP.fromfile("your file name here") && or use the sample code you had working with GETPICT()
	m.lorect	= .rectangle.new(750, 500, 1500, 1000) && define the wanted rectangle here
	m.locropped	= m.lobmp.CLONE(m.lorect)
ENDWITH

Take a look around, there are lots of gdiplusx samples, also there are even more gdiplus samples in other languages, eg c#. This needs a little experience with those programming languages, but gdiplus x has an object structure in _screen.system.drawing, which is made similar to the .NET gdi+ name spaces system.drawing.x.y, so the part of the code using gdiplus is very similar.

Bye, Olaf.
 
hi everyone,

thankx for all the inputs and ideas and advice .... iam using the gdiplus ... it's working perfectly fine ... and here is what i have done .. this is the code behind my "Take Snap-Shot" Button :-

THISFORM.COntainer1.Image1.Visible=.F.

*** CLICKING PHOTO NOW ***
DECLARE INTEGER ShellExecute IN shell32.DLL ;
INTEGER hndWin, ;
STRING cAction, ;
STRING cFileName, ;
STRING cParams, ;
STRING cDir, ;
INTEGER nShowWin

CACTION = "open"
CFILENAME=ADDBS(JUSTDRIVE(FULLPATH(SYS(16))))+'Item-Photos\Others\NKRemoteLibTest.EXE'

SHELLEXECUTE(0,CACTION,CFILENAME,"","",1)
***

MESSAGEBOX("DOWNLOADING IMAGE FROM CAMERA ..... ",4096,5000,"Item-Photos")

IMAGEFILES1="C:\NKREMOTE\"
IMAGEFILES2="'"+IMAGEFILES1+"*.*"+"'"

LOCAL ARRAY MYIMAGE[1,1]
ADIR(MYIMAGE,&IMAGEFILES2)

CREATE CURSOR MYIMAGE (FLNM C(150))
APPEND FROM ARRAY MYIMAGE

*** IMAGE RESAMPLING PROCESS ***

DO ADDBS(JUSTDRIVE(FULLPATH(SYS(16))))+'Item-Photos\APPS\SYSTEM.APP'

WITH _SCREEN.SYSTEM.DRAWING

* DIMENSIONS FOR NEW SLIGHTLY SMALLER - IMAGE (ORIGINAL IMAGE SIZE FROM CAMERA IS 2999 x 2000)
LOCAL INWIDTH,INHEIGHT
INWIDTH=599
INHEIGHT=400

* SELECTING THE IMAGE FILE TO CONVERT
LOCAL LOSRCIMAGE AS XFCBITMAP
LOSRCIMAGE=.BITMAP.NEW('C:\NKREMOTE\'+ALLTRIM(MYIMAGE.FLNM))

* CREATING NEW IMAGE IN THE DEFINED DIMENSIONS
LOCAL LORESIZED AS XFCBITMAP
LORESIZED=.BITMAP.NEW(INWIDTH,INHEIGHT,.IMAGING.PIXELFORMAT.FORMAT32BPPARGB)

* SETTING IMAGE RESOLUTION QUALITY SAME AS THE SOURCE
LORESIZED.SETRESOLUTION(LOSRCIMAGE.HORIZONTALRESOLUTION,LOSRCIMAGE.VERTICALRESOLUTION)

* RESAMPLING OF THE NEW IMAGE TO HAVE IT IN HIGH PICTURE QUALITY
LOCAL LOGFX AS XFCGRAPHICS
LOGFX=.GRAPHICS.FROMIMAGE(LORESIZED)

LOGFX.SMOOTHINGMODE=.DRAWING2D.SMOOTHINGMODE.HIGHQUALITY
LOGFX.INTERPOLATIONMODE=.DRAWING2D.INTERPOLATIONMODE.HIGHQUALITYBICUBIC
LOGFX.DRAWIMAGE(LOSRCIMAGE,0,0,INWIDTH,INHEIGHT)

* SAVING THE NEW RESAMPLED IMAGE AS .PNG FILE
RESAMPLED="'"+ADDBS(JUSTDRIVE(FULLPATH(SYS(16))))+'ITEM-PHOTOS\ITEM-PHOTOS\'+ALLTRIM(THISFORM.COntainer1.Text1.VALUE)+".PNG'"
LORESIZED.SAVE(&RESAMPLED,.IMAGING.IMAGEFORMAT.PNG)

* LOADING RESAMPLED image
LOCAL lobmp AS xfcbitmap
m.lobmp = .BITMAP.fromfile(&RESAMPLED)

*** IMAGE CROPING PROCESS ***
LOCAL locropped AS xfcbitmap

* CROP IMAGE WITH DEFINITIONS FROM THE FORM - center position , top position , width & height
m.locropped = m.lobmp.CLONE(.rectangle.new(THISFORM.COntainer1.TEXt4.Value,THISFORM.COntainer1.TXTTOP.Value,THISFORM.COntainer1.TEXt2.Value,THISFORM.COntainer1.TEXt3.Value))
CROPED="'"+ADDBS(JUSTDRIVE(FULLPATH(SYS(16))))+'ITEM-PHOTOS\CROPED-PHOTOS\'+ALLTRIM(THISFORM.COntainer1.Text1.VALUE)+".PNG'"
m.locropped.SAVE(&CROPED, .imaging.imageformat.png)

ENDWITH

*===================================================================================================

MESSAGEBOX("PLEASE WAIT WHILE THE IMAGE IS BEING RESAMPLED & PREPARED FOR DISPLAY ..... ",4096,1750,"Item-Photos")

THISFORM.COntainer1.Image1.PICTURE=&CROPED
THISFORM.COntainer1.Image1.VISIBLE=.T.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top