bitmap_ptr finalize(bool showProgress = true) {
		if (chunks.empty()) {
			return nullptr;
		}
		if (showProgress) {
			std::cout << "Adding all accepted chunks to the final image\n";
		}
		
		const auto it = chunks.begin();
		bitmap_ptr firstChunk = GenericLoader(*it);
		
		auto currentHeight = 0;

		const auto type = FreeImage_GetImageType(firstChunk.get());
		
		const auto bpp = FreeImage_GetBPP(firstChunk.get());
		
		bitmap_ptr finalImage(FreeImage_AllocateT(type, width, height, bpp));

		auto RGBChunkWorker = [=, &finalImage, &currentHeight](const std::string& el)
		{
			bitmap_ptr chunk = GenericLoader(el);
			auto chunkHeight = FreeImage_GetHeight(chunk.get());
			auto chunk_img = FreeImage_Copy(chunk.get(), 0, 0, this->width, chunkHeight);
			if (chunk_img) {
				FreeImage_Paste(finalImage.get(), chunk_img, 0, currentHeight, 256);
			}
			currentHeight += chunkHeight;
		};

		std::for_each(chunks.begin(), chunks.end(), RGBChunkWorker);
		return finalImage;
	}
Example #2
0
/**
Poisson solver based on a multigrig algorithm. 
This routine solves a Poisson equation, remap result pixels to [0..1] and returns the solution. 
NB: The input image is first stored inside a square image whose size is (2^j + 1)x(2^j + 1) for some integer j, 
where j is such that 2^j is the nearest larger dimension corresponding to MAX(image width, image height). 
@param Laplacian Laplacian image
@param ncycle Number of cycles in the multigrid algorithm (usually 2 or 3)
@return Returns the solved PDE equations if successful, returns NULL otherwise
*/
FIBITMAP* DLL_CALLCONV 
FreeImage_MultigridPoissonSolver(FIBITMAP *Laplacian, int ncycle) {
	if(!Laplacian) return NULL;

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

	// get nearest larger dimension length that is acceptable by the algorithm
	int n = MAX(width, height);
	int size = 0;
	while((n >>= 1) > 0) size++;
	// size must be of the form 2^j + 1 for some integer j
	size = 1 + (1 << (size + 1));

	// allocate a temporary square image I
	FIBITMAP *I = FreeImage_AllocateT(FIT_FLOAT, size, size);
	if(!I) return NULL;

	// copy Laplacian into I and shift pixels to create a boundary
	FreeImage_Paste(I, Laplacian, 1, 1, 255);

	// solve the PDE equation
	fmg_mglin(I, size, ncycle);

	// shift pixels back
	FIBITMAP *U = FreeImage_Copy(I, 1, 1, width + 1, height + 1);
	FreeImage_Unload(I);

	// remap pixels to [0..1]
	NormalizeY(U, 0, 1);

	// return the integrated image
	return U;
}
Example #3
0
BOOL fipImage::pasteSubImage(fipImage& src, int left, int top, int alpha) {
	if(_dib) {
		BOOL bResult = FreeImage_Paste(_dib, src._dib, left, top, alpha);
		_bHasChanged = TRUE;
		return bResult;
	}
	return FALSE;
}
  void storeFreeImage(const Ref<Image>& img, const FileName& fileName)
  {
      FIBITMAP* dib = FreeImage_Allocate((int)img->width, (int)img->height, 24);

      for(size_t y = 0; y < img->height; y++)
      {
          for(size_t x = 0; x < img->width; x++)
          {
			  Color4 c = img->get(x, y);
              
              RGBQUAD Value = {0};
              Value.rgbRed   = (BYTE)(clamp(c.r) * 255.0f);
              Value.rgbGreen = (BYTE)(clamp(c.g) * 255.0f);
              Value.rgbBlue  = (BYTE)(clamp(c.b) * 255.0f);

              FreeImage_SetPixelColor(dib, (unsigned int)x, (unsigned int)y, &Value);
          }
      }

      FIBITMAP* fiLogo = loadWatermark();

      unsigned int LogoWidth  = FreeImage_GetWidth (fiLogo);
      unsigned int LogoHeight = FreeImage_GetHeight(fiLogo);

      if(LogoWidth > img->width || LogoHeight > img->height)
      {
          FreeImage_Unload(fiLogo);

          FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName.c_str());
          if(FreeImage_FIFSupportsWriting(fif))
              FreeImage_Save(fif, dib, fileName.c_str());

          FreeImage_Unload(dib);
      }
      else
      {
          int x_pos = (int)img->width  - LogoWidth;
          int y_pos = (int)img->height - LogoHeight;

          FIBITMAP* fiFG = FreeImage_Allocate((int)img->width, (int)img->height, 32);
          BOOL b = FreeImage_Paste(fiFG, fiLogo, x_pos, y_pos, 255);
          FreeImage_Unload(fiLogo);

          FIBITMAP* fiNew = FreeImage_Composite(fiFG, FALSE, NULL, dib);
          FreeImage_Unload(dib);

          FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(fileName.c_str());

          int save_flags = 0;
          if(fif == FIF_JPEG)
              save_flags = JPEG_QUALITYSUPERB | JPEG_BASELINE | JPEG_OPTIMIZE;

          if(FreeImage_FIFSupportsWriting(fif))
              FreeImage_Save(fif, fiNew, fileName.c_str(), save_flags);

          FreeImage_Unload(fiNew);
      }
  }
Example #5
0
/*
 * Arguments: dest. dib_udata, source dib_udata,
 *	left (number), top (number), alpha (number)
 * Returns: [dest. dib_udata]
 */
static int
dib_paste (lua_State *L)
{
  FIBITMAP *dst_dib = lua_unboxpointer(L, 1, DIB_TYPENAME);
  FIBITMAP *src_dib = lua_unboxpointer(L, 2, DIB_TYPENAME);
  const int left = lua_tointeger(L, 3);
  const int top = lua_tointeger(L, 4);
  const int alpha = lua_tointeger(L, 5);

  return dib_checkerror(L,
   FreeImage_Paste(dst_dib, src_dib, left, top, alpha) ? dst_dib : NULL);
}
FIBITMAP * gifcat(char gifpath[MAXGIFCOUNT][MAXPATHCHAR], unsigned gifPathCount) // 将多张图片连接为一张图片
{
	FIBITMAP * hImageAll ;
	unsigned ImgHeightAll = 0 ;
	FIBITMAP * hImage[MAXGIFCOUNT] ;
	unsigned ImgHeight[MAXGIFCOUNT] ;
	unsigned ImgWidth ;
	RGBQUAD * palSrc ;
	RGBQUAD * palAll ;
	unsigned n , NowYPos = 0 ;
//	---
	for ( n=0; n < gifPathCount; ++n) {
		hImage[n] = FreeImage_Load(FIF_GIF, gifpath[n], 0);
		ImgHeight[n] = FreeImage_GetHeight(hImage[n]) ;
		ImgHeightAll += ImgHeight[n] ;
	}
	ImgWidth = FreeImage_GetWidth(hImage[0]) ;

	hImageAll = FreeImage_Allocate(ImgWidth, ImgHeightAll, 8, 0, 0, 0);  //创建目标图像
	palAll = FreeImage_GetPalette(hImageAll);       // 复制调色板
	palSrc = FreeImage_GetPalette(hImage[0]);
	for (n = 0; n < 256; ++n) {
		palAll[n].rgbRed = palSrc[n].rgbRed ;
		palAll[n].rgbGreen = palSrc[n].rgbGreen ;
		palAll[n].rgbBlue = palSrc[n].rgbBlue ;
	}
	palAll[70].rgbRed = 255   ;
	palAll[70].rgbGreen = 255 ;
	palAll[70].rgbBlue = 255  ;

	for ( n=0; n < gifPathCount; ++n) {  // 粘贴图像
		FreeImage_Paste(hImageAll, hImage[n], 0, NowYPos, 300) ;
		NowYPos += ImgHeight[n] ;
		FreeImage_Unload(hImage[n]) ;
	}
	return hImageAll ;
}
Example #7
0
void Image::_load(string sFilename)
{
	errlog << "Load " << sFilename << endl;
	//image format
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	//pointer to the image, once loaded
	FIBITMAP *dib(0);
	//pointer to the image data
	BYTE* bits(0);
	//image width and height
	unsigned int width(0), height(0);
	
	//check the file signature and deduce its format
	fif = FreeImage_GetFileType(sFilename.c_str(), 0);
	//if still unknown, try to guess the file format from the file extension
	if(fif == FIF_UNKNOWN) 
		fif = FreeImage_GetFIFFromFilename(sFilename.c_str());
	//if still unkown, return failure
	if(fif == FIF_UNKNOWN)
	{
		errlog << "Unknown image type for file " << sFilename << endl;
		return;
	}
  
	//check that the plugin has reading capabilities and load the file
	if(FreeImage_FIFSupportsReading(fif))
		dib = FreeImage_Load(fif, sFilename.c_str());
	else
		errlog << "File " << sFilename << " doesn't support reading." << endl;
	//if the image failed to load, return failure
	if(!dib)
	{
		errlog << "Error loading image " << sFilename.c_str() << endl;
		return;
	}  
	//retrieve the image data
  
	//get the image width and height
	width = FreeImage_GetWidth(dib);
	height = FreeImage_GetHeight(dib);
  
	int w = power_of_two(width);
	int h = power_of_two(height);
	int mode, modeflip;
	if(FreeImage_GetBPP(dib) == 24) // RGB 24bit
	{
		mode = GL_RGB;
		modeflip = GL_BGR;
	}
	else if(FreeImage_GetBPP(dib) == 32)  // RGBA 32bit
	{
		mode = GL_RGBA;
		modeflip = GL_BGRA;
	}
	FIBITMAP *bitmap2 = FreeImage_Allocate(w, h, FreeImage_GetBPP(dib));
	FreeImage_Paste(bitmap2, dib, 0, 0, 255);
	FreeImage_FlipVertical(bitmap2);  //Apparently, FreeImage handles this strangely. Flipping beforehand doesn't work right.
	FreeImage_Unload(dib);
  
	bits = FreeImage_GetBits(bitmap2);	//if this somehow one of these failed (they shouldn't), return failure
	if((bits == 0) || (width == 0) || (height == 0))
	{
		errlog << "Something went terribly horribly wrong with getting image bits; just sit and wait for the singularity" << endl;
		return;
	}
  
	//generate an OpenGL texture ID for this texture
	m_iWidth = width;
	m_iHeight = height;
	m_iRealWidth = w;
	m_iRealHeight = h;
	glGenTextures(1, &m_hTex);
	//bind to the new texture ID
	glBindTexture(GL_TEXTURE_2D, m_hTex);
	//store the texture data for OpenGL use
	glTexImage2D(GL_TEXTURE_2D, 0, mode, w, h, 0, modeflip, GL_UNSIGNED_BYTE, bits);
  
	//Free FreeImage's copy of the data
	FreeImage_Unload(bitmap2);
}
Example #8
0
File: loader.c Project: eXeC64/imv
static void *bg_next_frame(void *data)
{
  struct imv_loader *ldr = data;

  pthread_mutex_lock(&ldr->lock);
  int num_frames = ldr->num_frames;
  if(num_frames < 2) {
    pthread_mutex_unlock(&ldr->lock);
    return NULL;
  }

  FITAG *tag = NULL;
  char disposal_method = 0;
  int frame_time = 0;
  short top = 0;
  short left = 0;

  ldr->cur_frame = ldr->next_frame;
  ldr->next_frame = (ldr->cur_frame + 1) % ldr->num_frames;
  FIBITMAP *frame = FreeImage_LockPage(ldr->mbmp, ldr->cur_frame);
  FIBITMAP *frame32 = FreeImage_ConvertTo32Bits(frame);

  /* First frame is always going to use the raw frame */
  if(ldr->cur_frame > 0) {
    FreeImage_GetMetadata(FIMD_ANIMATION, frame, "DisposalMethod", &tag);
    if(FreeImage_GetTagValue(tag)) {
      disposal_method = *(char*)FreeImage_GetTagValue(tag);
    }
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameLeft", &tag);
  if(FreeImage_GetTagValue(tag)) {
    left = *(short*)FreeImage_GetTagValue(tag);
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTop", &tag);
  if(FreeImage_GetTagValue(tag)) {
    top = *(short*)FreeImage_GetTagValue(tag);
  }

  FreeImage_GetMetadata(FIMD_ANIMATION, frame, "FrameTime", &tag);
  if(FreeImage_GetTagValue(tag)) {
    frame_time = *(int*)FreeImage_GetTagValue(tag);
  }

  /* some gifs don't provide a frame time at all */
  if(frame_time == 0) {
    frame_time = 100;
  }
  ldr->frame_time += frame_time * 0.001;

  FreeImage_UnlockPage(ldr->mbmp, frame, 0);

  /* If this frame is inset, we need to expand it for compositing */
  if(ldr->width != (int)FreeImage_GetWidth(frame32) ||
     ldr->height != (int)FreeImage_GetHeight(frame32)) {
    FIBITMAP *expanded = FreeImage_Allocate(ldr->width, ldr->height, 32, 0,0,0);
    FreeImage_Paste(expanded, frame32, left, top, 255);
    FreeImage_Unload(frame32);
    frame32 = expanded;
  }

  switch(disposal_method) {
    case 0: /* nothing specified, fall through to compositing */
    case 1: /* composite over previous frame */
      if(ldr->bmp && ldr->cur_frame > 0) {
        FIBITMAP *bg_frame = FreeImage_ConvertTo24Bits(ldr->bmp);
        FreeImage_Unload(ldr->bmp);
        FIBITMAP *comp = FreeImage_Composite(frame32, 1, NULL, bg_frame);
        FreeImage_Unload(bg_frame);
        FreeImage_Unload(frame32);
        ldr->bmp = comp;
      } else {
        /* No previous frame, just render directly */
        if(ldr->bmp) {
          FreeImage_Unload(ldr->bmp);
        }
        ldr->bmp = frame32;
      }
      break;
    case 2: /* TODO - set to background, composite over that */
      if(ldr->bmp) {
        FreeImage_Unload(ldr->bmp);
      }
      ldr->bmp = frame32;
      break;
    case 3: /* TODO - restore to previous content */
      if(ldr->bmp) {
        FreeImage_Unload(ldr->bmp);
      }
      ldr->bmp = frame32;
      break;
  }

  if(ldr->out_bmp) {
    FreeImage_Unload(ldr->out_bmp);
  }
  ldr->out_bmp = FreeImage_Clone(ldr->bmp);

  pthread_mutex_unlock(&ldr->lock);
  return NULL;
}
FOX_DLL unsigned gifsplit(char * pngprefix, char gifpath[MAXGIFCOUNT][MAXPATHCHAR], unsigned gifPathCount, unsigned ScreenWidth, unsigned ScreenHeight, unsigned bSaveToBuff, FIBITMAP * hImageList[MAXOUTBUFCOUNT]) // 1 base count
{
//	------ 声明开始
//	FIBITMAP * hImageList[MAXOUTBUFCOUNT] ;  // 输出 himage 数组, 首元素包含数组长度
	FIBITMAP * hPicTemplete;
	FIBITMAP * hImage ;
	FIBITMAP * hPicBlank;
	BYTE * pBit ;
	unsigned ImgPitch, ImgWidth, ImgHeight ;

	char pathPNG[MAXPATHCHAR];
	unsigned n;

//	ylist
	unsigned xsplitcount = 0 ;   // X 切割份数
	POSLIST ylist[MAXYLIST] ;
	unsigned TextLineCount = 0 ; // Y 切割份数
	LineLR yinfo[MAXYLIST] ;
	unsigned StartX, EndX ;

//	joblist
	JOBLIST joblist[MAXJOBLIST]  ;
	unsigned NowJobCount ; // joblist item count

	unsigned nNewPicCount = 0 ;

//	------- 语句开始

	hImage = gifcat(gifpath, gifPathCount) ; // 将多张图片连接为一张图片
	hPicTemplete = CreateTemplete(hImage, ScreenWidth, ScreenHeight) ; // 创建空白PNG模版
	

		ImgWidth = FreeImage_GetWidth(hImage) ;
		ImgHeight = FreeImage_GetHeight(hImage) ;
		ImgPitch = FreeImage_GetPitch(hImage) ;
		pBit = FreeImage_GetBits(hImage) ;

		TextLineCount = GetYList(ylist , pBit , ImgPitch, ImgWidth, ImgHeight) ;  // 获取 Y 分割列表
		StartX = GetLeftBorderX(0, ImgWidth, 0, ImgHeight, pBit, ImgPitch) ;
		EndX = GetRightBorderX(ImgWidth - 1, ImgWidth, 0, ImgHeight, pBit, ImgPitch) ;
		yinfo[0].left = StartX ;
		yinfo[0].right = EndX ;
		GetLineBorder(yinfo, ylist, TextLineCount, pBit, ImgPitch, ImgWidth, ImgHeight) ; // 每行左右坐标
		yinfo[TextLineCount].left = StartX ;
		yinfo[TextLineCount].right = EndX ;

		NowJobCount = NewGetJobList(joblist, yinfo, ylist, TextLineCount, ScreenWidth, ScreenHeight, ImgWidth, ImgHeight, pBit, ImgPitch, bSaveToBuff) ; // 新版任务列表,只根据屏幕宽度取X坐标,不固定


	// 根据joblist 来生成 png
	for (n = 0; n < NowJobCount; n++) {
//		printf("任务编号: %d , A: %d , L: %d , R: %d , T: %d , B: %d , nL: %d , nT: %d, R-L: %d\n", n, joblist[n].action, joblist[n].left, joblist[n].right, joblist[n].top, joblist[n].bottom, joblist[n].newleft, joblist[n].newtop, joblist[n].right - joblist[n].left) ; // 调试用
		if ( ( joblist[n].action >= 1 ) && ( joblist[n].action != 5 ) )
			hPicBlank = FreeImage_Clone(hPicTemplete);

		FreeImage_Paste(hPicBlank, FreeImage_Copy(hImage, joblist[n].left, joblist[n].top, joblist[n].right, joblist[n].bottom), joblist[n].newleft, joblist[n].newtop, 300);

		if ( joblist[n].action >= 5 ) {
			++nNewPicCount ;
			sprintf(pathPNG, "%s%03d.png", pngprefix, nNewPicCount) ;
			printf("生成PNG %d : %s\n", nNewPicCount , pathPNG) ;

			if ( bSaveToBuff == 1 ) { // 输出到buff
				hImageList[nNewPicCount-1] = hPicBlank ;
			} else {  // 输出到文件
				FreeImage_Save(FIF_PNG, hPicBlank, pathPNG) ;
				FreeImage_Unload(hPicBlank) ;
			}
		}
	}
	return nNewPicCount;
}
Example #10
0
/**
 * Alpha blend or combine a sub part image with the current dib image.
 * For images of type FITBITMAP only: The bit depth of the dst bitmap must be greater than or
 * equal to the bit depth of the src. Upper promotion of src is done internally, without modifying
 * src. Supported dst bit depth equals to 1, 4, 8, 16, 24 or 32.
 *
 * For any other image type: The image type of the dst bitmap must be equal to the image type
 * of the src. The alpha parameter is always ignored and the source image is combined to the
 * destination image.
 *
 * The function returns TRUE if successful, FALSE otherwise (including if the one or both images is not loaded).
 * @param pIm               Pointer to an image object, that is going to be pasted (Alpha blended and/or combined with the current image)
 * @param pX                X Coordenate
 * @param pY                Y Coordenate
 * @param pAlpha            Alpha value on the destination image
 */
bool IND_Image::pasteImage(IND_Image *pIm, int pX, int pY, int pAlpha) {
	// No image loaded
	if (!isImageLoaded() || !pIm->isImageLoaded()) return false;

	return FreeImage_Paste(getFreeImageHandle(), pIm->getFreeImageHandle(), pX, pY, pAlpha) != 0;
}
Example #11
0
void poImage::composite(poImage *img, poPoint into, float blend) {
	FreeImage_Paste(bitmap, img->bitmap, into.x, into.y, blend*256);
}