示例#1
0
BOOL fipImage::colorQuantize(FREE_IMAGE_QUANTIZE algorithm) {
	if(_dib) {
		FIBITMAP *dib8 = FreeImage_ColorQuantize(_dib, algorithm);
		return replace(dib8);
	}
	return FALSE;
}
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(const ofPixels_<PixelType> & _pix, const std::string& _fileName, ofImageQualityType qualityLevel) {
	// Make a local copy.
	ofPixels_<PixelType> pix = _pix;

	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);
	std::string 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);
	}
}
示例#4
0
    void save_stream_to_image(Stream* str, GfxImageColorMap* color_map,
                              int width, int height, GBool mono,
                              char* file_name, GBool mask)
    {
        // read raw data from memory
        FIBITMAP* fib;
        if (mono)
        {
            int size = height * ((width + 7) / 8);
            unsigned char* buf = (unsigned char*)malloc(size);
            if (!buf) return;
            unsigned char* p = buf;
            str->reset();
            for (int i = 0; i < size; i++)
                *p++ = str->getChar();
            str->close();

            fib = FreeImage_ConvertFromRawBits(buf, width, height,
                                               (width + 7) / 8, 1, 0, 0, 0, 1);
            RGBQUAD* pal = FreeImage_GetPalette(fib);
            pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = (mask ? 0 : 255);
            pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = (mask ? 255 : 0);
            free(buf);
        }
        else
        {
            int row_size = width * 3;
            if (row_size % 4)
                row_size += (4 - row_size % 4);
            unsigned char* buf = (unsigned char*)malloc(height * row_size);
            if (!buf) return;

            ImageStream* img_str =
                new ImageStream(str, width, color_map->getNumPixelComps(),
                                color_map->getBits());
            img_str->reset();

            Guchar* p;
            unsigned char* pbuf;
            GfxRGB rgb;

            for (int y = 0; y < height; ++y)
            {
                p = img_str->getLine();
                pbuf = buf + row_size * y;
                for (int x = 0; x < width; ++x)
                {
                    color_map->getRGB(p, &rgb);
                    pbuf[0] = colToByte(rgb.b);
                    pbuf[1] = colToByte(rgb.g);
                    pbuf[2] = colToByte(rgb.r);
                    p += color_map->getNumPixelComps();
                    pbuf += 3;
                }
            }

            fib = FreeImage_ConvertFromRawBits(buf, width, height, row_size,
                                               24, 0, 0, 0, 1);
            delete img_str;
            free(buf);
        }

        // adjust color depth
        if (fif == FIF_GIF && !mono)
        {
            FIBITMAP* fib_temp = fib;
            fib = FreeImage_ColorQuantize(fib_temp, FIQ_WUQUANT);
            FreeImage_Unload(fib_temp);
        }
        else if (fif == FIF_JPEG && mono)
        {
            FIBITMAP* fib_temp = fib;
            fib = FreeImage_ConvertTo8Bits(fib_temp);
            FreeImage_Unload(fib_temp);
        }

        // save
        FreeImage_SetDotsPerMeterX(fib, 72 * 10000 / 254);
        FreeImage_SetDotsPerMeterY(fib, 72 * 10000 / 254);
        int flag = 0;
        if (fif == FIF_JPEG) flag = jpg_quality;
        else if (fif == FIF_TIFF && tiff_jpeg && !mono) flag = TIFF_JPEG;
        if (!FreeImage_Save(fif, fib, file_name, flag))
            error(-1, "Couldn't create file '%s'", file_name);
        FreeImage_Unload(fib);
    }
FIBITMAP * DLL_CALLCONV 
FreeImage_Rescale(FIBITMAP *src, int dst_width, int dst_height, FREE_IMAGE_FILTER filter) {
	FIBITMAP *dst = NULL;

	if (!src || (dst_width <= 0) || (dst_height <= 0)) {
		return NULL;
	}

	// select the filter
	CGenericFilter *pFilter = NULL;
	switch(filter) {
		case FILTER_BOX:
			pFilter = new CBoxFilter();
			break;
		case FILTER_BICUBIC:
			pFilter = new CBicubicFilter();
			break;
		case FILTER_BILINEAR:
			pFilter = new CBilinearFilter();
			break;
		case FILTER_BSPLINE:
			pFilter = new CBSplineFilter();
			break;
		case FILTER_CATMULLROM:
			pFilter = new CCatmullRomFilter();
			break;
		case FILTER_LANCZOS3:
			pFilter = new CLanczos3Filter();
			break;
	}

	CResizeEngine Engine(pFilter);

	// perform upsampling or downsampling

	if((FreeImage_GetBPP(src) == 4) || (FreeImage_GetColorType(src) == FIC_PALETTE)) {
		// special case for 4-bit images or color map indexed images ...
		if(FreeImage_IsTransparent(src) == FALSE) {
			FIBITMAP *src24 = NULL;
			FIBITMAP *dst24 = NULL;
			try {
				// transparent conversion to 24-bit (any transparency table will be destroyed)
				src24 = FreeImage_ConvertTo24Bits(src);
				if(!src24) throw(1);
				// perform upsampling or downsampling
				dst24 = Engine.scale(src24, dst_width, dst_height);
				if(!dst24) throw(1);
				// color quantize to 8-bit
				dst = FreeImage_ColorQuantize(dst24, FIQ_WUQUANT);
				// free and return
				FreeImage_Unload(src24);
				FreeImage_Unload(dst24);
			} catch(int) {
				if(src24) FreeImage_Unload(src24);
				if(dst24) FreeImage_Unload(dst24);
			}
		} else {
			FIBITMAP *src32 = NULL;
			try {
				// transparent conversion to 32-bit (keep transparency)
				src32 = FreeImage_ConvertTo32Bits(src);
				if(!src32) throw(1);
				// perform upsampling or downsampling
				dst = Engine.scale(src32, dst_width, dst_height);
				if(!dst) throw(1);
				// free and return
				FreeImage_Unload(src32);
			} catch(int) {
				if(src32) FreeImage_Unload(src32);
				if(dst) FreeImage_Unload(dst);
			}
		}
	}
	else if((FreeImage_GetBPP(src) == 16) && (FreeImage_GetImageType(src) == FIT_BITMAP)) {
		// convert 16-bit RGB to 24-bit
		FIBITMAP *src24 = NULL;
		try {
			// transparent conversion to 24-bit (any transparency table will be destroyed)
			src24 = FreeImage_ConvertTo24Bits(src);
			if(!src24) throw(1);
			// perform upsampling or downsampling
			dst = Engine.scale(src24, dst_width, dst_height);
			if(!dst) throw(1);
			// free and return
			FreeImage_Unload(src24);
		} catch(int) {
			if(src24) FreeImage_Unload(src24);
			if(dst) FreeImage_Unload(dst);
		}
	}
	else {
		// normal case : 
		// 1- or 8-bit greyscale, 24- or 32-bit RGB(A) images
		// 16-bit greyscale, 48- or 64-bit RGB(A) images
		// 32-bit float, 96- or 128-bit RGB(A) float images
		dst = Engine.scale(src, dst_width, dst_height);
	}


	delete pFilter;

	return dst;
}
void doLazyFixer(std::string pathIn,  std::string imgFileIn,
                std::string pathOut,
                LazyFixTool_Setup &setup)
{
    if(Files::hasSuffix(imgFileIn, "m.gif"))
        return; //Skip mask files

    std::string imgPathIn = pathIn + "/" + imgFileIn;
    std::string maskPathIn;

    std::cout << imgPathIn;
    std::cout.flush();

    std::string maskFileIn;
    getGifMask(maskFileIn, imgFileIn);

    maskPathIn = pathIn + "/" + maskFileIn;

    //Create backup in case of source and target are same
    if(!setup.noMakeBackup && (pathIn == pathOut))
    {
        DirMan backupDir(pathIn + "/_backup");
        bool ret = false;
        if(!backupDir.exists())
        {
            std::cout << ".MKDIR.";
            std::cout.flush();
            if(!backupDir.mkdir(""))
            {
                std::cout << ".FAIL!.";
                std::cout.flush();
                goto skipBackpDir;
            }
        }
        ret |= Files::copyFile(backupDir.absolutePath() + "/" + imgFileIn,  imgPathIn,  false);
        ret |= Files::copyFile(backupDir.absolutePath() + "/" + maskFileIn, maskPathIn, false);

        if(ret)
            setup.count_backups++;
        skipBackpDir:;
    }

    FIBITMAP *image = loadImage(imgPathIn);
    if(!image)
    {
        setup.count_failed++;
        std::cout << "...CAN'T OPEN!\n";
        std::cout.flush();
        return;
    }

    FIBITMAP *mask = NULL;
    if(Files::fileExists(maskPathIn))
    {
        bool hasMask = mergeBitBltToRGBA(image, maskPathIn);
        if(hasMask) // Split in case is mask presented
            splitRGBAtoBitBlt(image, mask);
    }

    bool isFail = false;
    if(image)
    {
        std::string outPathF = pathOut + "/" + imgFileIn;
        FIBITMAP *image8 = FreeImage_ColorQuantize(image, FIQ_WUQUANT);
        if(image8)
        {
            int ret = FreeImage_Save(FIF_GIF, image8, outPathF.c_str());
            if(!ret)
            {
                std::cout << "...F-WRT FAILED!\n";
                isFail = true;
            }
            FreeImage_Unload(image8);
        }
        else
            isFail = true;
        FreeImage_Unload(image);

    }
    else
    {
        isFail = true;
    }

    if(mask)
    {
        std::string outPathB = pathOut + "/" + maskFileIn;
        FIBITMAP *mask8  = FreeImage_ColorQuantize(mask, FIQ_WUQUANT);
        if(mask8)
        {
            int ret = FreeImage_Save(FIF_GIF, mask8, outPathB.c_str());
            if(!ret)
            {
                std::cout << "...B-WRT FAILED!\n";
                isFail = true;
            }
            FreeImage_Unload(mask8);
        }
        else
            isFail = true;
        FreeImage_Unload(mask);
    } else {
        setup.count_nomask++;
    }

    if(isFail)
    {
        setup.count_failed++;
        std::cout << "...FAILED!\n";
    } else {
        setup.count_success++;
        std::cout << "...done\n";
    }

    std::cout.flush();
}