void putBmpIntoPixels(FIBITMAP * bmp, ofPixels_<PixelType> &pix, bool swapForLittleEndian = true) { // convert to correct type depending on type of input bmp and PixelType FIBITMAP* bmpConverted = NULL; FREE_IMAGE_TYPE imgType = FreeImage_GetImageType(bmp); if(sizeof(PixelType)==1 && (FreeImage_GetColorType(bmp) == FIC_PALETTE || FreeImage_GetBPP(bmp) < 8 || imgType!=FIT_BITMAP)) { if(FreeImage_IsTransparent(bmp)) { bmpConverted = FreeImage_ConvertTo32Bits(bmp); } else { bmpConverted = FreeImage_ConvertTo24Bits(bmp); } bmp = bmpConverted; }else if(sizeof(PixelType)==2 && imgType!=FIT_UINT16 && imgType!=FIT_RGB16 && imgType!=FIT_RGBA16){ if(FreeImage_IsTransparent(bmp)) { bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBA16); } else { bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGB16); } bmp = bmpConverted; }else if(sizeof(PixelType)==4 && imgType!=FIT_FLOAT && imgType!=FIT_RGBF && imgType!=FIT_RGBAF){ if(FreeImage_IsTransparent(bmp)) { bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBAF); } else { bmpConverted = FreeImage_ConvertToType(bmp,FIT_RGBF); } bmp = bmpConverted; } unsigned int width = FreeImage_GetWidth(bmp); unsigned int height = FreeImage_GetHeight(bmp); unsigned int bpp = FreeImage_GetBPP(bmp); unsigned int channels = (bpp / sizeof(PixelType)) / 8; unsigned int pitch = FreeImage_GetPitch(bmp); // ofPixels are top left, FIBITMAP is bottom left FreeImage_FlipVertical(bmp); unsigned char* bmpBits = FreeImage_GetBits(bmp); if(bmpBits != NULL) { pix.setFromAlignedPixels((PixelType*) bmpBits, width, height, channels, pitch); } else { ofLogError("ofImage") << "putBmpIntoPixels(): unable to set ofPixels from FIBITMAP"; } if(bmpConverted != NULL) { FreeImage_Unload(bmpConverted); } #ifdef TARGET_LITTLE_ENDIAN if(swapForLittleEndian && sizeof(PixelType) == 1) { pix.swapRgb(); } #endif }
void putBmpIntoPixels(FIBITMAP * bmp, ofPixels_<PixelType> &pix, bool swapForLittleEndian = true) { // some images use a palette, or <8 bpp, so convert them to raster 8-bit channels FIBITMAP* bmpConverted = NULL; if(FreeImage_GetColorType(bmp) == FIC_PALETTE || FreeImage_GetBPP(bmp) < 8) { if(FreeImage_IsTransparent(bmp)) { bmpConverted = FreeImage_ConvertTo32Bits(bmp); } else { bmpConverted = FreeImage_ConvertTo24Bits(bmp); } bmp = bmpConverted; } unsigned int width = FreeImage_GetWidth(bmp); unsigned int height = FreeImage_GetHeight(bmp); unsigned int bpp = FreeImage_GetBPP(bmp); unsigned int channels = (bpp / sizeof(PixelType)) / 8; unsigned int pitch = FreeImage_GetPitch(bmp); // ofPixels are top left, FIBITMAP is bottom left FreeImage_FlipVertical(bmp); unsigned char* bmpBits = FreeImage_GetBits(bmp); if(bmpBits != NULL) { pix.setFromAlignedPixels((PixelType*) bmpBits, width, height, channels, pitch); } else { ofLogError() << "ofImage::putBmpIntoPixels() unable to set ofPixels from FIBITMAP"; } if(bmpConverted != NULL) { FreeImage_Unload(bmpConverted); } #ifdef TARGET_LITTLE_ENDIAN if(swapForLittleEndian && sizeof(PixelType) == 1) { pix.swapRgb(); } #endif }
static void saveImage(ofPixels_<PixelType> & pix, ofBuffer & buffer, ofImageFormat format, ofImageQualityType qualityLevel) { //thanks to alvaro casinelli for the implementation ofInitFreeImage(); if (pix.isAllocated() == false){ ofLog(OF_LOG_ERROR,"error saving image - pixels aren't allocated"); return; } #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1) { pix.swapRgb(); } #endif FIBITMAP * bmp = getBmpFromPixels(pix); #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1) { pix.swapRgb(); } #endif if (bmp) // bitmap successfully created { // (b) open a memory stream to compress the image onto mem_buffer: // FIMEMORY *hmem = FreeImage_OpenMemory(); // (c) encode and save the image to the memory (on dib FIBITMAP image): // if(FREE_IMAGE_FORMAT(format) == FIF_JPEG) { int quality = JPEG_QUALITYSUPERB; switch(qualityLevel) { case OF_IMAGE_QUALITY_WORST: quality = JPEG_QUALITYBAD; break; case OF_IMAGE_QUALITY_LOW: quality = JPEG_QUALITYAVERAGE; break; case OF_IMAGE_QUALITY_MEDIUM: quality = JPEG_QUALITYNORMAL; break; case OF_IMAGE_QUALITY_HIGH: quality = JPEG_QUALITYGOOD; break; case OF_IMAGE_QUALITY_BEST: quality = JPEG_QUALITYSUPERB; break; } FreeImage_SaveToMemory(FIF_JPEG, bmp, hmem, quality); }else{ FreeImage_SaveToMemory((FREE_IMAGE_FORMAT)format, bmp, hmem); } /* NOTE: at this point, hmem contains the entire data in memory stored in fif format. the amount of space used by the memory is equal to file_size: long file_size = FreeImage_TellMemory(hmem); but can also be retrieved by FreeImage_AcquireMemory that retrieves both the length of the buffer, and the buffer memory address. */ #ifdef TARGET_WIN32 DWORD size_in_bytes = 0; #else uint32_t size_in_bytes = 0; #endif // Save compressed data on mem_buffer // note: FreeImage_AquireMemory allocates space for aux_mem_buffer): // unsigned char *mem_buffer = NULL; if (!FreeImage_AcquireMemory(hmem, &mem_buffer, &size_in_bytes)) cout << "Error aquiring compressed image from memory" << endl; /* Now, before closing the memory stream, copy the content of mem_buffer to an auxiliary buffer */ buffer.set((char*)mem_buffer,size_in_bytes); // Finally, close the FIBITMAP object, or we will get a memory leak: FreeImage_Unload(bmp); // Close the memory stream (otherwise we may get a memory leak). FreeImage_CloseMemory(hmem); } }
static void saveImage(ofPixels_<PixelType> & pix, string fileName, ofImageQualityType qualityLevel) { ofInitFreeImage(); if (pix.isAllocated() == false){ ofLog(OF_LOG_ERROR,"error saving image - pixels aren't allocated"); return; } #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1) { pix.swapRgb(); } #endif FIBITMAP * bmp = getBmpFromPixels(pix); #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1) { pix.swapRgb(); } #endif fileName = ofToDataPath(fileName); 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_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(fif == FIF_JPEG) { int quality = JPEG_QUALITYSUPERB; switch(qualityLevel) { case OF_IMAGE_QUALITY_WORST: quality = JPEG_QUALITYBAD; break; case OF_IMAGE_QUALITY_LOW: quality = JPEG_QUALITYAVERAGE; break; case OF_IMAGE_QUALITY_MEDIUM: quality = JPEG_QUALITYNORMAL; break; case OF_IMAGE_QUALITY_HIGH: quality = JPEG_QUALITYGOOD; break; case OF_IMAGE_QUALITY_BEST: quality = JPEG_QUALITYSUPERB; break; } FreeImage_Save(fif, bmp, fileName.c_str(), quality); } else { if(qualityLevel != OF_IMAGE_QUALITY_BEST) { ofLogWarning() << "ofImageCompressionType only applies to JPEG images, ignoring value"; } if (fif == FIF_GIF) { FIBITMAP* convertedBmp; if(pix.getImageType() == OF_IMAGE_COLOR_ALPHA) { // this just converts the image to grayscale so it can save something convertedBmp = FreeImage_ConvertTo8Bits(bmp); } else { // this will create a 256-color palette from the image convertedBmp = FreeImage_ColorQuantize(bmp, FIQ_NNQUANT); } FreeImage_Save(fif, convertedBmp, fileName.c_str()); if (convertedBmp != NULL){ FreeImage_Unload(convertedBmp); } } else { FreeImage_Save(fif, bmp, fileName.c_str()); } } } if (bmp != NULL){ FreeImage_Unload(bmp); } }
static void saveImage(ofPixels_<PixelType> & pix, string fileName, ofImageQualityType qualityLevel) { ofInitFreeImage(); if (pix.isAllocated() == false){ ofLogError("ofImage") << "saveImage(): couldn't save \"" << fileName << "\", pixels are not allocated"; return; } #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1 && (pix.getPixelFormat()==OF_PIXELS_RGB || pix.getPixelFormat()==OF_PIXELS_RGBA)) { pix.swapRgb(); } #endif FIBITMAP * bmp = getBmpFromPixels(pix); #ifdef TARGET_LITTLE_ENDIAN if(sizeof(PixelType) == 1 && (pix.getPixelFormat()==OF_PIXELS_BGR || pix.getPixelFormat()==OF_PIXELS_BGRA)) { pix.swapRgb(); } #endif ofFilePath::createEnclosingDirectory(fileName); fileName = ofToDataPath(fileName); 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_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { if(fif == FIF_JPEG) { int quality = JPEG_QUALITYSUPERB; switch(qualityLevel) { case OF_IMAGE_QUALITY_WORST: quality = JPEG_QUALITYBAD; break; case OF_IMAGE_QUALITY_LOW: quality = JPEG_QUALITYAVERAGE; break; case OF_IMAGE_QUALITY_MEDIUM: quality = JPEG_QUALITYNORMAL; break; case OF_IMAGE_QUALITY_HIGH: quality = JPEG_QUALITYGOOD; break; case OF_IMAGE_QUALITY_BEST: quality = JPEG_QUALITYSUPERB; break; } FreeImage_Save(fif, bmp, fileName.c_str(), quality); } else { if(qualityLevel != OF_IMAGE_QUALITY_BEST) { ofLogWarning("ofImage") << "saveImage(): ofImageCompressionType only applies to JPEGs," << " ignoring value for \" "<< fileName << "\""; } if (fif == FIF_GIF) { FIBITMAP* convertedBmp; if(pix.getImageType() == OF_IMAGE_COLOR_ALPHA) { // this just converts the image to grayscale so it can save something convertedBmp = FreeImage_ConvertTo8Bits(bmp); } else { // this will create a 256-color palette from the image convertedBmp = FreeImage_ColorQuantize(bmp, FIQ_NNQUANT); } FreeImage_Save(fif, convertedBmp, fileName.c_str()); if (convertedBmp != nullptr){ FreeImage_Unload(convertedBmp); } } else { FreeImage_Save(fif, bmp, fileName.c_str()); } } } if (bmp != nullptr){ FreeImage_Unload(bmp); } }