Esempio n. 1
0
/**
Performs a 5 by 5 gaussian filtering using two 1D convolutions, 
followed by a subsampling by 2. 
@param dib Input image
@return Returns a blurred image of size SIZE(dib)/2
@see GaussianPyramid
*/
static FIBITMAP* GaussianLevel5x5(FIBITMAP *dib) {
	FIBITMAP *h_dib = NULL, *v_dib = NULL, *dst = NULL;
	float *src_pixel, *dst_pixel;

	try {
		const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
		if(image_type != FIT_FLOAT) throw(1);

		const unsigned width = FreeImage_GetWidth(dib);
		const unsigned height = FreeImage_GetHeight(dib);

		h_dib = FreeImage_AllocateT(image_type, width, height);
		v_dib = FreeImage_AllocateT(image_type, width, height);
		if(!h_dib || !v_dib) throw(1);

		const unsigned pitch = FreeImage_GetPitch(dib) / sizeof(float);

		// horizontal convolution dib -> h_dib

		src_pixel = (float*)FreeImage_GetBits(dib);
		dst_pixel = (float*)FreeImage_GetBits(h_dib);

		for(unsigned y = 0; y < height; y++) {
			// work on line y
			for(unsigned x = 2; x < width - 2; x++) {
				dst_pixel[x] = src_pixel[x-2] + src_pixel[x+2] + 4 * (src_pixel[x-1] + src_pixel[x+1]) + 6 * src_pixel[x];
				dst_pixel[x] /= 16;
			}
			// boundary mirroring
			dst_pixel[0] = (2 * src_pixel[2] + 8 * src_pixel[1] + 6 * src_pixel[0]) / 16;
			dst_pixel[1] = (src_pixel[3] + 4 * (src_pixel[0] + src_pixel[2]) + 7 * src_pixel[1]) / 16;
			dst_pixel[width-2] = (src_pixel[width-4] + 5 * src_pixel[width-1] + 4 * src_pixel[width-3] + 6 * src_pixel[width-2]) / 16;
			dst_pixel[width-1] = (src_pixel[width-3] + 5 * src_pixel[width-2] + 10 * src_pixel[width-1]) / 16;

			// next line
			src_pixel += pitch;
			dst_pixel += pitch;
		}

		// vertical convolution h_dib -> v_dib

		src_pixel = (float*)FreeImage_GetBits(h_dib);
		dst_pixel = (float*)FreeImage_GetBits(v_dib);

		for(unsigned x = 0; x < width; x++) {		
			// work on column x
			for(unsigned y = 2; y < height - 2; y++) {
				const unsigned index = y*pitch + x;
				dst_pixel[index] = src_pixel[index-2*pitch] + src_pixel[index+2*pitch] + 4 * (src_pixel[index-pitch] + src_pixel[index+pitch]) + 6 * src_pixel[index];
				dst_pixel[index] /= 16;
			}
			// boundary mirroring
			dst_pixel[x] = (2 * src_pixel[x+2*pitch] + 8 * src_pixel[x+pitch] + 6 * src_pixel[x]) / 16;
			dst_pixel[x+pitch] = (src_pixel[x+3*pitch] + 4 * (src_pixel[x] + src_pixel[x+2*pitch]) + 7 * src_pixel[x+pitch]) / 16;
			dst_pixel[(height-2)*pitch+x] = (src_pixel[(height-4)*pitch+x] + 5 * src_pixel[(height-1)*pitch+x] + 4 * src_pixel[(height-3)*pitch+x] + 6 * src_pixel[(height-2)*pitch+x]) / 16;
			dst_pixel[(height-1)*pitch+x] = (src_pixel[(height-3)*pitch+x] + 5 * src_pixel[(height-2)*pitch+x] + 10 * src_pixel[(height-1)*pitch+x]) / 16;
		}

		FreeImage_Unload(h_dib); h_dib = NULL;

		// perform downsampling

		dst = FreeImage_Rescale(v_dib, width/2, height/2, FILTER_BILINEAR);

		FreeImage_Unload(v_dib);

		return dst;

	} catch(int) {
		if(h_dib) FreeImage_Unload(h_dib);
		if(v_dib) FreeImage_Unload(v_dib);
		if(dst) FreeImage_Unload(dst);
		return NULL;
	}
}
Esempio n. 2
0
FIBITMAP * DLL_CALLCONV
FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert) {
	FIBITMAP *thumbnail = NULL;
	int new_width, new_height;

	if(!FreeImage_HasPixels(dib) || (max_pixel_size <= 0)) return NULL;

	int width	= FreeImage_GetWidth(dib);
	int height = FreeImage_GetHeight(dib);

	if(max_pixel_size == 0) max_pixel_size = 1;

	if((width < max_pixel_size) && (height < max_pixel_size)) {
		// image is smaller than the requested thumbnail
		return FreeImage_Clone(dib);
	}

	if(width > height) {
		new_width = max_pixel_size;
		// change image height with the same ratio
		double ratio = ((double)new_width / (double)width);
		new_height = (int)(height * ratio + 0.5);
		if(new_height == 0) new_height = 1;
	} else {
		new_height = max_pixel_size;
		// change image width with the same ratio
		double ratio = ((double)new_height / (double)height);
		new_width = (int)(width * ratio + 0.5);
		if(new_width == 0) new_width = 1;
	}

	const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);

	// perform downsampling using a bilinear interpolation

	switch(image_type) {
		case FIT_BITMAP:
		case FIT_UINT16:
		case FIT_RGB16:
		case FIT_RGBA16:
		case FIT_FLOAT:
		case FIT_RGBF:
		case FIT_RGBAF:
		{
			FREE_IMAGE_FILTER filter = FILTER_BILINEAR;
			thumbnail = FreeImage_Rescale(dib, new_width, new_height, filter);
		}
		break;

		case FIT_INT16:
		case FIT_UINT32:
		case FIT_INT32:
		case FIT_DOUBLE:
		case FIT_COMPLEX:
		default:
			// cannot rescale this kind of image
			thumbnail = NULL;
			break;
	}

	if((thumbnail != NULL) && (image_type != FIT_BITMAP) && convert) {
		// convert to a standard bitmap
		FIBITMAP *bitmap = NULL;
		switch((int)image_type) {
			case FIT_UINT16:
				bitmap = FreeImage_ConvertTo8Bits(thumbnail);
				break;
			case FIT_RGB16:
				bitmap = FreeImage_ConvertTo24Bits(thumbnail);
				break;
			case FIT_RGBA16:
				bitmap = FreeImage_ConvertTo32Bits(thumbnail);
				break;
			case FIT_FLOAT:
				bitmap = FreeImage_ConvertToStandardType(thumbnail, TRUE);
				break;
			case FIT_RGBF:
				bitmap = FreeImage_ToneMapping(thumbnail, FITMO_DRAGO03);
				break;
			case FIT_RGBAF:
				// no way to keep the transparency yet ...
				FIBITMAP *rgbf = FreeImage_ConvertToRGBF(thumbnail);
				bitmap = FreeImage_ToneMapping(rgbf, FITMO_DRAGO03);
				FreeImage_Unload(rgbf);
				break;
		}
		if(bitmap != NULL) {
			FreeImage_Unload(thumbnail);
			thumbnail = bitmap;
		}
	}

	// copy metadata from src to dst
	FreeImage_CloneMetadata(thumbnail, dib);
	
	return thumbnail;
}
Esempio n. 3
0
void clBitmap::Rescale( int NewW, int NewH )
{
	FreeImage_Rescale( clPtr<clBitmap>( this ), NewW, NewH );
}
Esempio n. 4
0
/**
Compute the gradient attenuation function PHI(x, y)
@param gradients Gradient pyramid (nlevels levels)
@param avgGrad Average gradient on each level (array of size nlevels)
@param nlevels Number of levels
@param alpha Parameter alpha in the paper
@param beta Parameter beta in the paper
@return Returns the attenuation matrix Phi if successful, returns NULL otherwise
*/
static FIBITMAP* PhiMatrix(FIBITMAP **gradients, float *avgGrad, int nlevels, float alpha, float beta) {
	float *src_pixel, *dst_pixel;
	FIBITMAP **phi = NULL;

	try {
		phi = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
		if(!phi) throw(1);
		memset(phi, 0, nlevels * sizeof(FIBITMAP*));

		for(int k = nlevels-1; k >= 0; k--) {
			// compute phi(k)

			FIBITMAP *Gk = gradients[k];

			const unsigned width = FreeImage_GetWidth(Gk);
			const unsigned height = FreeImage_GetHeight(Gk);
			const unsigned pitch = FreeImage_GetPitch(Gk) / sizeof(float);

			// parameter alpha is 0.1 times the average gradient magnitude
			// also, note the factor of 2**k in the denominator; 
			// that is there to correct for the fact that an average gradient avgGrad(H) over 2**k pixels 
			// in the original image will appear as a gradient grad(Hk) = 2**k*avgGrad(H) over a single pixel in Hk. 
			float ALPHA =  alpha * avgGrad[k] * (float)((int)1 << k);
			if(ALPHA == 0) ALPHA = EPSILON;

			phi[k] = FreeImage_AllocateT(FIT_FLOAT, width, height);
			if(!phi[k]) throw(1);
			
			src_pixel = (float*)FreeImage_GetBits(Gk);
			dst_pixel = (float*)FreeImage_GetBits(phi[k]);
			for(unsigned y = 0; y < height; y++) {
				for(unsigned x = 0; x < width; x++) {
					// compute (alpha / grad) * (grad / alpha) ** beta
					const float v = src_pixel[x] / ALPHA;
					const float value = (float)pow((float)v, (float)(beta-1));
					dst_pixel[x] = (value > 1) ? 1 : value;
				}
				// next line
				src_pixel += pitch;
				dst_pixel += pitch;
			}

			if(k < nlevels-1) {
				// compute PHI(k) = L( PHI(k+1) ) * phi(k)
				FIBITMAP *L = FreeImage_Rescale(phi[k+1], width, height, FILTER_BILINEAR);
				if(!L) throw(1);

				src_pixel = (float*)FreeImage_GetBits(L);
				dst_pixel = (float*)FreeImage_GetBits(phi[k]);
				for(unsigned y = 0; y < height; y++) {
					for(unsigned x = 0; x < width; x++) {
						dst_pixel[x] *= src_pixel[x];
					}
					// next line
					src_pixel += pitch;
					dst_pixel += pitch;
				}

				FreeImage_Unload(L);

				// PHI(k+1) is no longer needed
				FreeImage_Unload(phi[k+1]);
				phi[k+1] = NULL;
			}

			// next level
		}

		// get the final result and return
		FIBITMAP *dst = phi[0];

		free(phi);

		return dst;

	} catch(int) {
		if(phi) {
			for(int k = nlevels-1; k >= 0; k--) {
				if(phi[k]) FreeImage_Unload(phi[k]);
			}
			free(phi);
		}
		return NULL;
	}
}
Esempio n. 5
0
	void FreeImage::_updateSize() {
		FIBITMAP * resizedImage = FreeImage_Rescale( this -> freeImage, this -> size.x, this -> size.y, ( FREE_IMAGE_FILTER ) this -> resampleFilter );
		FreeImage_Unload( freeImage );
		freeImage = resizedImage;
		this -> stride = FreeImage_GetPitch( this -> freeImage );
	}
Esempio n. 6
0
MOboolean
moTextureBuffer::LoadImage( moText p_ImageName, moBitmap* pImage, int indeximage  ) {

    MOboolean res = false;
    FIBITMAP* _pImage = (FIBITMAP*)pImage;
	FIBITMAP* pImageResult = NULL;
	FIBITMAP* pImageCropped = NULL;
	FIBITMAP* pImageScaled = NULL;
    /*
	if ( m_width!=FreeImage_GetWidth(_pImage) || m_height!=FreeImage_GetHeight(_pImage) ) {
		//CROP MODE
		pImageCropped = FreeImage_Copy( _pImage, m_XSource , m_YSource , m_XSource + m_SourceWidth , m_YSource+m_SourceHeight );
		pImageResult = pImageCropped;

	} else
	*/

	pImageResult = _pImage;

    int w, h;
	if ( ( FreeImage_GetWidth(_pImage) % 4 ) != 0 || ( FreeImage_GetHeight(_pImage) % 4) == 0 ) {

        w = FreeImage_GetWidth(_pImage) / 4;
        w = w * 4;

        h = FreeImage_GetHeight(_pImage) / 4;
        h = h * 4;

        pImageScaled = FreeImage_Rescale( pImageResult, w, h, FILTER_BICUBIC );
		if (pImageScaled) {
			//FreeImage_Unload(pImageResult);
			pImageResult = pImageScaled;
		}
	}


	FreeImage_AdjustContrast( pImageResult, 0 );
	FreeImage_AdjustBrightness( pImageResult, 0 );



	//RESCALE: NOTE NECESARRY HERE
	//quizas podamos definir un máximo para el tamaño tanto ancho como alto
	//o como proporción
	//forzar proporcion y esas cosas....
	/*
	if ( m_width != m_SourceWidth || m_height != m_SourceHeight ) {

		//FILTER_BOX Box, pulse, Fourier window, 1st order (constant) B-Spline
		//FILTER_BILINEAR Bilinear filter
		//FILTER_BSPLINE 4th order (cubic) B-Spline
		//FILTER_BICUBIC Mitchell and Netravali's two-param cubic filter
		//FILTER_CATMULLROM Catmull-Rom spline, Overhauser spline
		//FILTER_LANCZOS3
		pImageScaled = FreeImage_Rescale( pImageResult, m_width, m_height, FILTER_BICUBIC );
		if (pImageScaled) {
			FreeImage_Unload(pImageResult);
			pImageResult = pImageScaled;
		}
	}
	*/

    moTextureMemory* pTextureMemory = NULL;

    int idx = m_pResourceManager->GetTextureMan()->AddTexture( MO_TYPE_TEXTUREMEMORY, p_ImageName );

	if (idx>-1) {
	    pTextureMemory = (moTextureMemory*) m_pResourceManager->GetTextureMan()->GetTexture(idx);
        if (pTextureMemory) {
            if (pTextureMemory->BuildFromBitmap( pImageResult, m_BufferFormat )) {

                m_Frames.Add(pTextureMemory);

                int contrastlevel = pTextureMemory->GetContrast() / 2000;
                int luminancelevel = (int)((float)pTextureMemory->GetLuminance() / (float)2.56 ) - 1;

                MODebug2->Message( moText("moTextureBuffer::LoadImage success : ") + (moText)pTextureMemory->GetName());
                #ifdef _DEBUG
                MODebug2->Message( moText("moTextureBuffer::LoadImage success : ") + (moText)pTextureMemory->GetName()
                                + moText(" width:") + IntToStr(pTextureMemory->GetWidth())
                                + moText(" height:") + IntToStr(pTextureMemory->GetHeight())
                                + moText(" luminance:") + IntToStr(pTextureMemory->GetLuminance())
                                + moText(" luminancelevel:") + IntToStr(luminancelevel) +
                                + moText(" contrast:") + IntToStr(pTextureMemory->GetContrast())
                                + moText(" contrastlevel:") + IntToStr(contrastlevel) );
                #endif

                contrastlevel = 0;

                if (luminancelevel>=100) {
                        MODebug2->Error( moText("moTextureBuffer::LoadImage Error: luminance out of bound:")+ IntToStr(pTextureMemory->GetLuminance()) );
                } else {
                        if (max_luminance<luminancelevel) {
                            max_luminance = luminancelevel;
                        } else if (min_luminance>luminancelevel) {
                            min_luminance = luminancelevel;
                        }
                }
                if (contrastlevel>=10) {
                        MODebug2->Error( moText("moTextureBuffer::LoadImage Error: contrast out of bound:")+ IntToStr(pTextureMemory->GetContrast()) );
                }
                if (0<=luminancelevel && luminancelevel<100 && 0<=contrastlevel && contrastlevel<10) {

                    m_pBufferLevels[luminancelevel][contrastlevel].Add( pTextureMemory );

                    int icc = momin( m_pBufferLevels[luminancelevel][contrastlevel].Count(), 99 );
                    LevelDiagram[ (luminancelevel + icc*100)*3 ] = 250;
                    LevelDiagram[ (luminancelevel+1 + icc*100)*3 ] = 250;
                    LevelDiagram[ (luminancelevel+2 + icc*100)*3 ] = 250;
                }

                res = true;
            } else {
                res = false;
                MODebug2->Error( moText("moTextureBuffer::LoadImage Error loading image:")+(moText)pTextureMemory->GetName());
            }
        }
	}

	if (pImageResult!=_pImage)
		FreeImage_Unload(pImageResult);

	//m_nFrames = m_Frames.Count();
	//m_fFramesPerSecond = 25.0;

	return (res);
}
static struct graphics_image_priv *
image_new(struct graphics_priv *gr, struct graphics_image_methods *meth,
	  char *path, int *w, int *h, struct point *hot, int rotation)
{
#if USE_FREEIMAGE
	FIBITMAP *image;
	RGBQUAD aPixel;
	unsigned char *data;
	int width, height, i, j;
	struct graphics_image_priv *gi;
	//check if image already exists in hashmap
	struct graphics_image_priv *curr_elem =
	    g_hash_table_lookup(hImageData, path);
	if (curr_elem == &image_error) {
		//found but couldn't be loaded
		return NULL;
	} else if (curr_elem) {
		//found and OK -> use hastable entry
		*w = curr_elem->w;
		*h = curr_elem->h;
		hot->x = curr_elem->w / 2 - 1;
		hot->y = curr_elem->h / 2 - 1;
		return curr_elem;
	} else {
		if (strlen(path) < 4) {
			g_hash_table_insert(hImageData, g_strdup(path),
					    &image_error);
			return NULL;
		}
		char *ext_str = path + strlen(path) - 3;
		if (strstr(ext_str, "png") || strstr(path, "PNG")) {
			if ((image =
			     FreeImage_Load(FIF_PNG, path, 0)) == NULL) {
				g_hash_table_insert(hImageData,
						    g_strdup(path),
						    &image_error);
				return NULL;
			}
		} else if (strstr(ext_str, "xpm") || strstr(path, "XPM")) {
			if ((image =
			     FreeImage_Load(FIF_XPM, path, 0)) == NULL) {
				g_hash_table_insert(hImageData,
						    g_strdup(path),
						    &image_error);
				return NULL;
			}
		} else if (strstr(ext_str, "svg") || strstr(path, "SVG")) {
			char path_new[256];
			snprintf(path_new, strlen(path) - 3, "%s", path);
			strcat(path_new, "_48_48.png");

			if ((image =
			     FreeImage_Load(FIF_PNG, path_new,
					    0)) == NULL) {
				g_hash_table_insert(hImageData,
						    g_strdup(path),
						    &image_error);
				return NULL;
			}
		} else {
			g_hash_table_insert(hImageData, g_strdup(path),
					    &image_error);
			return NULL;
		}

		if (FreeImage_GetBPP(image) == 64) {
			FIBITMAP *image2;
			image2 = FreeImage_ConvertTo32Bits(image);
			FreeImage_Unload(image);
			image = image2;
		}
#if FREEIMAGE_MAJOR_VERSION*100+FREEIMAGE_MINOR_VERSION  >= 313
		if (rotation) {
			FIBITMAP *image2;
			image2 = FreeImage_Rotate(image, rotation, NULL);
			image = image2;
		}
#endif

		gi = g_new0(struct graphics_image_priv, 1);

		width = FreeImage_GetWidth(image);
		height = FreeImage_GetHeight(image);

		if ((*w != width || *h != height) && 0 < *w && 0 < *h) {
			FIBITMAP *image2;
			image2 = FreeImage_Rescale(image, *w, *h, NULL);
			FreeImage_Unload(image);
			image = image2;
			width = *w;
			height = *h;
		}

		data = (unsigned char *) malloc(width * height * 4);

		RGBQUAD *palette = NULL;
		if (FreeImage_GetBPP(image) == 8) {
			palette = FreeImage_GetPalette(image);
		}

		for (i = 0; i < height; i++) {
			for (j = 0; j < width; j++) {
				unsigned char idx;
				if (FreeImage_GetBPP(image) == 8) {
					FreeImage_GetPixelIndex(image, j,
								height -
								i - 1,
								&idx);
					data[4 * width * i + 4 * j + 0] =
					    palette[idx].rgbRed;
					data[4 * width * i + 4 * j + 1] =
					    palette[idx].rgbGreen;
					data[4 * width * i + 4 * j + 2] =
					    palette[idx].rgbBlue;
					data[4 * width * i + 4 * j + 3] =
					    255;
				} else if (FreeImage_GetBPP(image) == 16
					   || FreeImage_GetBPP(image) == 24
					   || FreeImage_GetBPP(image) ==
					   32) {
					FreeImage_GetPixelColor(image, j,
								height -
								i - 1,
								&aPixel);
					int transparent =
					    (aPixel.rgbRed == 0
					     && aPixel.rgbBlue == 0
					     && aPixel.rgbGreen == 0);
					data[4 * width * i + 4 * j + 0] =
					    transparent ? 0 : (aPixel.
							       rgbRed);
					data[4 * width * i + 4 * j + 1] =
					    (aPixel.rgbGreen);
					data[4 * width * i + 4 * j + 2] =
					    transparent ? 0 : (aPixel.
							       rgbBlue);
					data[4 * width * i + 4 * j + 3] =
					    transparent ? 0 : 255;

				}
			}
		}

		FreeImage_Unload(image);

		*w = width;
		*h = height;
		gi->w = width;
		gi->h = height;
		gi->hot_x = width / 2 - 1;
		gi->hot_y = height / 2 - 1;
		hot->x = width / 2 - 1;
		hot->y = height / 2 - 1;
		gi->data = data;
		gi->path = path;
		//add to hashtable
		g_hash_table_insert(hImageData, g_strdup(path), gi);
		return gi;
	}
#else
	return NULL;
#endif
}
Esempio n. 8
0
bool ImageLoader::
load(const std::string& imageName, bool isNormalMap)
{
	// 载入图片
	FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(imageName.c_str());
	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
	{
		if (mDIB)
			FreeImage_Unload(mDIB);
		mDIB = FreeImage_Load(fif, imageName.c_str());
		mFormat = fif;

		bool needScale = !oiram::fequal(config.imageScale, 1.0f);
		unsigned int newWidth = width(), newHeight = height(), newBpp = bpp();
		bool imagePowerOfTwo = config.imagePowerOfTwo;
		unsigned int imageMaxSize = config.imageMaxSize;

		// PVRTCII支持non-POT; ETC1和ETC2必须是POT, 最大尺寸限定在2048, 而且必须是正方形
		if (config.imageCompressionType == CT_ETC1 ||
			config.imageCompressionType == CT_ETC2)
		{
			imagePowerOfTwo = true;
			imageMaxSize = 2048;
		}

		// DXTC/PVRTC/ETCI有最小尺寸限制
		switch (config.imageCompressionType)
		{
		case CT_DXTC:
			if (newWidth < DXT_MIN_TEXWIDTH)
			{
				newWidth = DXT_MIN_TEXWIDTH;
				needScale = true;
			}
			if (newHeight < DXT_MIN_TEXHEIGHT)
			{
				newHeight = DXT_MIN_TEXHEIGHT;
				needScale = true;
			}
			// DXTC的尺寸必须是4的倍数
			{
				unsigned int	multiplesOfFourWidth = nearestMultiplesOfFour(newWidth),
								multiplesOfFourHeight = nearestMultiplesOfFour(newHeight);
				if (newWidth != multiplesOfFourWidth)
				{
					newWidth = multiplesOfFourWidth;
					needScale = true;
				}
				if (newHeight != multiplesOfFourHeight)
				{
					newHeight = multiplesOfFourHeight;
					needScale = true;
				}
			}
			break;

		case CT_ETC1:
		case CT_ETC2:
			if (newWidth < ETC_MIN_TEXWIDTH)
			{
				newWidth = ETC_MIN_TEXWIDTH;
				needScale = true;
			}
			if (newHeight < ETC_MIN_TEXHEIGHT)
			{
				newHeight = ETC_MIN_TEXHEIGHT;
				needScale = true;
			}
			break;

		case CT_PVRTC2_4BPP:
			if (newWidth < PVRTC4_MIN_TEXWIDTH)
			{
				newWidth = PVRTC4_MIN_TEXWIDTH;
				needScale = true;
			}
			if (newHeight < PVRTC4_MIN_TEXHEIGHT)
			{
				newHeight = PVRTC4_MIN_TEXHEIGHT;
				needScale = true;
			}
			break;
		}

		// 超出最大尺寸则按比例缩放
		if (imageMaxSize > 0 &&
			(newWidth > imageMaxSize || newHeight > imageMaxSize))
		{
			if (newWidth > newHeight)
			{
				float scale = static_cast<float>(newWidth) / newHeight;
				newWidth = imageMaxSize;
				newHeight = static_cast<unsigned int>(newWidth / scale);
			}
			else
			{
				float scale = static_cast<float>(newHeight) / newWidth;
				newHeight = imageMaxSize;
				newWidth = static_cast<unsigned int>(newHeight / scale);
			}
			needScale = true;
		}

		newWidth = static_cast<unsigned int>(newWidth * config.imageScale);
		newHeight = static_cast<unsigned int>(newHeight * config.imageScale);

		if (imagePowerOfTwo)
		{
			unsigned int potWidth = nearestPowerOfTwo(newWidth), potHeight = nearestPowerOfTwo(newHeight);
			if (newWidth != potWidth || newHeight != potHeight)
			{
				newWidth = potWidth;
				newHeight = potHeight;
				needScale = true;
			}
		}

		if (needScale)
		{
			FIBITMAP* rescaleDIB = FreeImage_Rescale(mDIB, newWidth, newHeight, FILTER_LANCZOS3);
			FreeImage_Unload(mDIB);
			mDIB = rescaleDIB;
		}

		return true;
	}

	return false;
}
Esempio n. 9
0
void task_glow_precalc() {
	FIMULTIBITMAP* anim = inputanim;
	float thresh=0.5;
	float gain=2.0;
	float blur=1.5;
	int frameskip=1;
	sscanf(args[1].c_str(), "%f", &thresh);
	sscanf(args[2].c_str(), "%f", &gain);
	sscanf(args[3].c_str(), "%f", &blur);
	sscanf(args[4].c_str(), "%i", &frameskip);
	

	int frameCount = FreeImage_GetPageCount(anim);
	vector<double> fb;
	for (int frame=0; frame<frameCount/frameskip; frame++) {
		FIBITMAP* fiBitmap = FreeImage_LockPage(anim,  frame*frameskip);
		FIBITMAP* grayBitmap = FreeImage_ConvertToGreyscale(fiBitmap);
		FreeImage_UnlockPage(anim, fiBitmap, FALSE);


		int width  = FreeImage_GetWidth(grayBitmap);
		int height = FreeImage_GetHeight(grayBitmap);


		// put into an array of doubles (phew)
		fb.resize(width*height);
		for (int y=0; y<height; y++) {
			BYTE* src = FreeImage_GetScanLine(grayBitmap, y);
			double* dst = &fb[y*width];
			for (int x=0; x<width; x++) {
				*dst++ = *src++ * (1.0/255);
			}
		}

		// threshold
		for (int i=0; i<(int)fb.size(); i++) {
			double& v = fb[i];
			v = (v-thresh)*gain;
			if (v<0) v=0;
		}

		// blur
		Blur(fb, width, height, blur);

		// put it back into greyBitmap
		for (int y=0; y<height; y++) {
			BYTE* dst = FreeImage_GetScanLine(grayBitmap, y);
			double* src = &fb[y*width];
			for (int x=0; x<width; x++) {
				double v = *src++ * 256;
				if (v<0) v=0;
				if (v>255) v=255;
				*dst++ = int(v);
			}
		}

		// downsample it to glowgrid
		FIBITMAP* smallBitmap = FreeImage_Rescale(grayBitmap, GLOWGRID_W, GLOWGRID_H, FILTER_BSPLINE);

		// print result (should use 4bpp not 8?)
		for (int y=0; y<GLOWGRID_H; y++) {
			BYTE* src = FreeImage_GetScanLine(smallBitmap, y);
			for (int x=0; x<GLOWGRID_W; x++) {
				putchar( *src++ );
			}
		}


	}


}
Esempio n. 10
0
	/// 图片另存为
	Bool FreeImageImage::saveToFile(ImageFileFormat eFileFormat, PCStr pszFileName, Rect* pRectClip, Point* pResize)
	{
		if (!isLoaded())
			return False;

		FREE_IMAGE_FORMAT eFreeImageFormat;
		switch (eFileFormat)
		{
		case IFF_BMP:
			eFreeImageFormat = FIF_BMP;
			break;
		case IFF_PNG:
			eFreeImageFormat = FIF_PNG;
			break;
		case IFF_JPG:
			eFreeImageFormat = FIF_JPEG;
			break;

		default:
			return False;
		}

		Point ptLeftTop(0, 0);
		Point ptSize(_ptImgSize.x, _ptImgSize.y);

		// 有裁减矩形
		if (pRectClip)
		{
			ptLeftTop.setPoint(pRectClip->x1, pRectClip->y1);
			ptSize = pRectClip->getSize();

			if (ptLeftTop.x + ptSize.x > _ptImgSize.x ||
				ptLeftTop.y + ptSize.y > _ptImgSize.y)
				return False;
		}

		FIBITMAP* pFIBitmap = FreeImage_Allocate(ptSize.x, ptSize.y, 32, 8, 8, 8);

		for(Int y = 0; y < ptSize.y; ++y)
		{
			// 需要考虑到 图片倒转
			Int nSrcFlipY = _ptImgSize.y - y - 1 - ptLeftTop.y;
			Int nDstFlipY = ptSize.y - y - 1;

			Color* pColorSrc = &_pImgData[_ptImgSize.x * nSrcFlipY + ptLeftTop.x];
			Color* pColorDst = (Color*)FreeImage_GetScanLine(pFIBitmap, nDstFlipY);

			memcpy(pColorDst, pColorSrc, sizeof(Color) * ptSize.x);
		}

		if (pResize)
		{
			if (0 == pResize->x && 0 < pResize->y)
				pResize->x = (Int16)((Real)pResize->y / (Real)ptSize.y * (Real)ptSize.x);

			if (0 == pResize->y && 0 < pResize->x)
				pResize->y = (Int16)((Real)pResize->x / (Real)ptSize.x * (Real)ptSize.y);

			pFIBitmap = FreeImage_Rescale(pFIBitmap, pResize->x, pResize->y, FILTER_BILINEAR);
		}

		Bool isSuccess = FreeImage_Save(eFreeImageFormat, pFIBitmap, pszFileName, PNG_DEFAULT);
		FreeImage_Unload(pFIBitmap);

		return isSuccess;
	}
Esempio n. 11
0
static INT_PTR serviceBmpFilterResizeBitmap(WPARAM wParam,LPARAM lParam)
{
	BITMAP bminfo;
	int width, height;
	int xOrig, yOrig, widthOrig, heightOrig;
	ResizeBitmap *info = (ResizeBitmap *) wParam;

	if (info == NULL || info->size != sizeof(ResizeBitmap)
		|| info->hBmp == NULL
		|| info->max_width < 0 || info->max_height < 0
		|| (info->fit & ~RESIZEBITMAP_FLAG_DONT_GROW) < RESIZEBITMAP_STRETCH
		|| (info->fit & ~RESIZEBITMAP_FLAG_DONT_GROW) > RESIZEBITMAP_MAKE_SQUARE)
		return 0;

	// Well, lets do it

	// Calc final size
	GetObject(info->hBmp, sizeof(bminfo), &bminfo);

	width = info->max_width == 0 ? bminfo.bmWidth : info->max_width;
	height = info->max_height == 0 ? bminfo.bmHeight : info->max_height;

	xOrig = 0;
	yOrig = 0;
	widthOrig = bminfo.bmWidth;
	heightOrig = bminfo.bmHeight;

	if (widthOrig == 0 || heightOrig == 0)
		return 0;

	switch(info->fit & ~RESIZEBITMAP_FLAG_DONT_GROW)
	{
		case RESIZEBITMAP_STRETCH:
		{
			// Do nothing
			break;
		}
		case RESIZEBITMAP_KEEP_PROPORTIONS:
		{
			if (height * widthOrig / heightOrig <= width)
			{
				if (info->fit & RESIZEBITMAP_FLAG_DONT_GROW)
					height = min(height, bminfo.bmHeight);
				width = height * widthOrig / heightOrig;
			}
			else
			{
				if (info->fit & RESIZEBITMAP_FLAG_DONT_GROW)
					width = min(width, bminfo.bmWidth);
				height = width * heightOrig / widthOrig;
			}

			break;
		}
		case RESIZEBITMAP_MAKE_SQUARE:
		{
			if (info->fit & RESIZEBITMAP_FLAG_DONT_GROW)
			{
				width = min(width, bminfo.bmWidth);
				height = min(height, bminfo.bmHeight);
			}

			width = height = min(width, height);
			// Do not break. Use crop calcs to make size
		}
		case RESIZEBITMAP_CROP:
		{
			if (heightOrig * width / height >= widthOrig)
			{
				heightOrig = widthOrig * height / width;
				yOrig = (bminfo.bmHeight - heightOrig) / 2;
			}
			else
			{
				widthOrig = heightOrig * width / height;
				xOrig = (bminfo.bmWidth - widthOrig) / 2;
			}

			break;
		}
	}

	if ((width == bminfo.bmWidth && height == bminfo.bmHeight)
		|| ((info->fit & RESIZEBITMAP_FLAG_DONT_GROW)
			&& !(info->fit & RESIZEBITMAP_MAKE_SQUARE)
			&& width > bminfo.bmWidth && height > bminfo.bmHeight))
	{
		// Do nothing
		return (INT_PTR)info->hBmp;
	}
	else
	{
		FIBITMAP *dib = FreeImage_CreateDIBFromHBITMAP(info->hBmp);
		if (dib == NULL)
			return NULL;

		FIBITMAP *dib_tmp;
		if (xOrig > 0 || yOrig > 0)
			dib_tmp = FreeImage_Copy(dib, xOrig, yOrig, xOrig + widthOrig, yOrig + heightOrig);
		else
			dib_tmp = dib;

		if (dib_tmp == NULL)
		{
			FreeImage_Unload(dib);
			return NULL;
		}

		FIBITMAP *dib_new = FreeImage_Rescale(dib_tmp, width, height, FILTER_CATMULLROM);

		HBITMAP bitmap_new = FreeImage_CreateHBITMAPFromDIB(dib_new);

		if (dib_new != dib_tmp)
			FreeImage_Unload(dib_new);
		if (dib_tmp != dib)
			FreeImage_Unload(dib_tmp);
        FreeImage_Unload(dib);

		return (INT_PTR)bitmap_new;
	}
}
Esempio n. 12
0
void poImage::resize(float w, float h) {
	FIBITMAP *img = FreeImage_Rescale(bitmap, w, h, FILTER_CATMULLROM);

	FreeImage_Unload(bitmap);
	bitmap = img;
}
Esempio n. 13
0
const QImage ImageLoaderFreeImage::imageAsRGB(const QSize &size) const
{
    const QSize resultSize = size.isValid() ? size : sizePixels();
    const bool isRGB24 = colorDataType() == Types::ColorTypeRGB && bitsPerPixel() == 24;
    const bool isARGB32 = colorDataType() == Types::ColorTypeRGBA && bitsPerPixel() == 32;
    QImage result(resultSize, isARGB32 ? QImage::Format_ARGB32 : QImage::Format_RGB32);

    const int width = resultSize.width();
    const int height = resultSize.height();
    const QSize sizePixels = this->sizePixels();

    FIBITMAP* originalImage = m_bitmap;
    FIBITMAP* temp24BPPImage = NULL;
    FIBITMAP* scaledImage = NULL;

    if (!(isRGB24 || isARGB32)) {
        if (colorDataType() == Types::ColorTypeCMYK) {
            const bool isCmykJpeg = isJpeg(); // Value range inverted
            temp24BPPImage = FreeImage_Allocate(sizePixels.width(), sizePixels.height(), 24);
            const unsigned int columnsCount = sizePixels.width();
            const unsigned int scanlinesCount = sizePixels.height();
            for (unsigned int scanline = 0; scanline < scanlinesCount; scanline++) {
                const BYTE* const cmykBits = FreeImage_GetScanLine(m_bitmap, scanline);
                tagRGBTRIPLE* const rgbBits = (tagRGBTRIPLE *)FreeImage_GetScanLine(temp24BPPImage, scanline);

                for (unsigned int column = 0; column < columnsCount; column++) {
                    const unsigned int cmykColumn = column * 4;

                    const QColor rgbColor = isCmykJpeg ?
                        QColor::fromCmyk(255 - cmykBits[cmykColumn], 255 - cmykBits[cmykColumn + 1], 255 - cmykBits[cmykColumn + 2], 255 - cmykBits[cmykColumn + 3])
                        : QColor::fromCmyk(cmykBits[cmykColumn], cmykBits[cmykColumn + 1], cmykBits[cmykColumn + 2], cmykBits[cmykColumn + 3]);

                    rgbBits[column].rgbtRed = (BYTE)rgbColor.red();
                    rgbBits[column].rgbtGreen = (BYTE)rgbColor.green();
                    rgbBits[column].rgbtBlue = (BYTE)rgbColor.blue();
                }
            }
        } else {
            temp24BPPImage = FreeImage_ConvertTo24Bits(originalImage);
        }
        originalImage = temp24BPPImage;
    }

    if (resultSize != sizePixels) {
        scaledImage = FreeImage_Rescale(originalImage, width, height, FILTER_BOX);
        originalImage = scaledImage;
    }

    for (int scanline = 0; scanline < height; scanline++) {
        QRgb *targetData = (QRgb*)result.scanLine(scanline);
        if (isARGB32) {
            const tagRGBQUAD *sourceRgba = (tagRGBQUAD*)FreeImage_GetScanLine(originalImage, height - scanline - 1);
            for (int column = 0; column < width; column++) {
                *targetData++ = qRgba(sourceRgba->rgbRed, sourceRgba->rgbGreen, sourceRgba->rgbBlue, sourceRgba->rgbReserved);
                sourceRgba++;
            }
        } else {
            const tagRGBTRIPLE *sourceRgb = (tagRGBTRIPLE*)FreeImage_GetScanLine(originalImage, height - scanline - 1);
            for (int column = 0; column < width; column++) {
                *targetData++ = qRgb(sourceRgb->rgbtRed, sourceRgb->rgbtGreen, sourceRgb->rgbtBlue);
                sourceRgb++;
            }
        }
    }

    if (temp24BPPImage)
        FreeImage_Unload(temp24BPPImage);

    if (scaledImage)
        FreeImage_Unload(scaledImage);

    return result;
}