saveImage file parameters

hi guys!

Is there a good way of using “img.saveImage(fileName)” to set things like image compression quality, for jpeg or similar?

I see that img.saveImage “will guess, based on the name, what filetype to save as,” but is there a way to set image filetype parameters?

thanks a bajillion!
jamie

Hi Jamie,

There is a way yes.
ofImage is using freeimage for all image i/o handling.

With freeimage you can set the JPEG quality and other parameters when you save.

The code that actually does the saving is:

FreeImage_Save(fif, bmp, fileName.c_str(), 0);

Where fif is a FREE_IMAGE_FORMAT structure that defines whether the image is a jpg, bmp, png etc. bmp is the image and the 0 is any flags you want to pass in.

If you look at page 10 of the freeimage documentation:
http://heanet.dl.sourceforge.net/sourceforge/freeimage/FreeImage3100.pdf

You can see a lit of flags that you can set. For jpeg there is:

JPEG JPEG_DEFAULT Saves with good quality (75:1)
JPEG_QUALITYSUPERB Saves with superb quality (100:1)
JPEG_QUALITYGOOD Saves with good quality (75:1)
JPEG_QUALITYNORMAL Saves with normal quality (50:1)
JPEG_QUALITYAVERAGE Saves with average quality (25:1)
JPEG_QUALITYBAD Saves with bad quality (10:1)
Integer X in [0…100] Save with quality X:1
JPEG_PROGRESSIVE Saves as a progressive JPEG file (use | to combine with
JPEG quality flags)

The reason we didn’t add all these things in is that the flags really depend on the type of image being saved and some image formats have flags that others don’t.

So what I would suggest is you either extend the ofImage class and add some extra functions that do what you need (recommended) or you sort of hack the functions into the existing ofImage class (not so recommended). Either way here is a saveJpg function that takes a 0 - 100 quality as a second argument.

  
  
//for the header file  
void	saveJpg(string fileName, int quality);  
  
//for the cpp file  
//----------------------------------------------------------  
void ofImage::saveJpg(string fileName, int quality){  
  
	fileName = ofToDataPath(fileName);  
	  
	if(quality > 100) quality = 100;  
	else if(quality <= 0)quality = 1;  
	  
	if (isValid()){  
		FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;  
		fif = FreeImage_GetFileType(fileName.c_str(), 0);  
		if(fif == FIF_UNKNOWN) {  
			// or guess via filename  
			fif = FreeImage_GetFIFFromFilename(fileName.c_str());  
		}  
		if((fif == FIF_JPEG) && FreeImage_FIFSupportsReading(fif)) {  
			// ok, if we are 0,0 top left, flip once, save and flip back  
			// this is because the native format for freeImage is 0,0 lower left  
			// there  be a smarter way to do this (ie, just draw upside down)  
			// as opposed to continually  
			FreeImage_FlipVertical(bmp);  
			FreeImage_Save(fif, bmp, fileName.c_str(), quality);  
			FreeImage_FlipVertical(bmp);  
		}else{  
			printf("saveJpg - requires you to save with .jpg extension - image not saved\n");  
			return;  
		}  
	}  
}  
  

At the very worst and if you know you are just going to be saving jpegs, you can just put the jpg flags into the last argument of FreeImage_Save.

that’s the shiznit - thanks man!
j