void CFontTexCreaterDlg::OnBnClickedExe()
{
	CComboBox* ccb = (CComboBox*)GetDlgItem(IDC_COMBO1) ;
	if( !ccb )
		return ;

	// font type
	int sel = ccb->GetCurSel() ;
	func_setFontInd( g_nFtIns , sel ) ;

	// texture size
	int texW = 1024 ;
	int texH = 1024 ;

	CEdit* pEdt = (CEdit*)GetDlgItem( IDC_EDT_TEXTURE_W ) ;
	if( pEdt )
	{
		wchar_t buf[256] ;
		pEdt->GetWindowText( buf , 256 ) ;
		texW = _wtoi( buf ) ;
	}

	pEdt = (CEdit*)GetDlgItem( IDC_EDT_TEXTURE_H ) ;
	if( pEdt )
	{
		wchar_t buf[256] ;
		pEdt->GetWindowText( buf , 256 ) ;
		texH = _wtoi( buf ) ;
	}

	char *canvas = new char[texW*texH] ;
	memset( canvas , 0 , texW*texH ) ;

	func_setCanvas( g_nFtIns ,canvas , texW , texH , 0 ) ;

	func_drawGlyphFromFile( g_nFtIns , "finalCode.txt" ) ;
	//func_drawAllGlyphs( g_nFtIns ) ;

	//
	{
		FreeImage_Initialise() ;

		FIBITMAP* bm = FreeImage_Allocate( texW , texH , 24 ) ;

		RGBQUAD clr ;

		for( int y = 0 ; y < texH ; y ++ )
		{
			for( int x = 0 ; x < texW ; x ++ )
			{
				char val = canvas[ y * texW + x ] ;

				clr.rgbBlue = val ;
				clr.rgbGreen = val ;
				clr.rgbRed = val ;
				clr.rgbReserved = 255 ;

				FreeImage_SetPixelColor( bm , x , texH - 1 - y , &clr ) ;
			}
		}
		//memcpy( bm->data , canvas , texW*texH ) ;

		FreeImage_Save( FIF_BMP , bm , "fontTex.bmp" ) ;

		FreeImage_Unload( bm ) ;

		FreeImage_DeInitialise() ;
	}

	//

	FILE* pf = fopen( "fontBuf" , "wb+" ) ;
	fwrite( canvas , texW * texH , 1 , pf ) ;
	fclose( pf ) ;

	//delete []canvas ;
}
Beispiel #2
0
void CFaceBitmap::ToFreeImage(FIBITMAP* image,int x,int y,RGBQUAD* fg)
{
	bool newfg=false;
	static int l = 2;
	RGBQUAD bg ;
	if(!fg)
	{
		fg = new RGBQUAD();
		memset(fg,0,sizeof(RGBQUAD));
		newfg = true;
	}
	int w = GetWidth();
	int h = GetHeight();
	for ( int i=0;i<h;i+=l )  
	{  
		l+=2;l%=3;
		for ( int j=0;j<w;j+=2 )  
		{  
			if((pBmp->buffer[i*w+j]!=0||pBmp->buffer[i*w+j]!=0|| pBmp->buffer[i*w+j]!=0))
			{
				FreeImage_SetPixelColor(image,j+x,h-i+y,fg);
				
			}
			else
			{
				
				FreeImage_GetPixelColor(image,j+x,h-i+y,&bg);
				FreeImage_SetPixelColor(image,j+x,h-i+y,&bg);
			}
		}  
		
	}
	if(newfg)
		delete fg;
}
void painter::rasterize_line(FIBITMAP* bitmap,
	boost::geometry::model::d2::point_xy<double> p1, boost::geometry::model::d2::point_xy<double> p2)
{
	int sx(round(p1.x())), sy(round(p1.y())), ex(round(p2.x())), ey(round(p2.y()));
	int dx(ex - sx), dy(ey - sy);
	FreeImage_SetPixelColor(bitmap, sx, sy, border_color);
	if (abs(dx) >= abs(dy))
	{
		if (dx == 0) return;
		int x = sx, xinc = dx > 0 ? 1 : -1;
		double y = sy, yinc = static_cast<double>(dy) / dx * xinc;
		while (x != ex)
		{
			x += xinc;
			y += yinc;
			FreeImage_SetPixelColor(bitmap, x, round(y), border_color);
		}
	}
	else
	{
		if (dy == 0) return;
		int y = sy, yinc = dy > 0 ? 1 : -1;
		double x = sx, xinc = static_cast<double>(dx) / dy * yinc;
		while (y != ey)
		{
			x += xinc;
			y += yinc;
			FreeImage_SetPixelColor(bitmap, round(x), y, border_color);
		}
	}
}
void Film :: writeImage(){
		if(AA_CONTROL){
			for(int k = 0; k < AA; k++){
				for(int j = 0; j < sizeY; j++){
					for(int i = 0; i < sizeX; i++){
						if(i == 0 && j == 0){
							aa[i + j * sizeY] = (matrix[i + 1 + j * sizeY] + matrix[i + 1 + (j + 1) * sizeY] + matrix[i + (j + 1) * sizeY]) / 3.0;
							continue;
						} else if((i + 1) == sizeX && (j + 1 == sizeY)) {
							aa[i + j * sizeY] = (matrix[i - 1 + j * sizeY] + matrix[i - 1 + (j - 1) * sizeY] + matrix[i + (j - 1) * sizeY]) / 3.0;
							continue;
						} else if((i + 1) == sizeX) {
							aa[i + j * sizeY] = (matrix[i - 1 + j * sizeY] + matrix[i - 1 + (j + 1) * sizeY] + matrix[i + (j + 1) * sizeY] + matrix[i + (j - 1) * sizeY] + matrix[i - 1 + (j - 1) * sizeY]) / 5.0;
							continue;
						} else if((j + 1) == sizeY) {
							aa[i + j * sizeY] = (matrix[i - 1 + j * sizeY] + matrix[i - 1 + (j - 1) * sizeY] + matrix[i + (j - 1) * sizeY] + matrix[i + 1 + j * sizeY] + matrix[i + 1 + (j - 1) * sizeY]) / 5.0;
							continue;
						} else if(i == 0){
							aa[i + j * sizeY] = (matrix[i + 1 + j * sizeY] + matrix[i + 1 + (j + 1) * sizeY] + matrix[i + (j + 1) * sizeY] + matrix[i + (j - 1) * sizeY] + matrix[i + 1 + (j - 1) * sizeY]) / 5.0;
							continue;
						} else if(j == 0){
							aa[i + j * sizeY] = (matrix[i - 1 + j * sizeY] + matrix[i - 1 + (j + 1) * sizeY] + matrix[i + (j + 1) * sizeY] + matrix[i + 1 + j * sizeY] + matrix[i + 1 + (j + 1) * sizeY]) / 5.0;
							continue;
						} else {
							aa[i + j * sizeY] = (matrix[i - 1 + (j + 1) * sizeY] + matrix[i + (j + 1) * sizeY] + matrix[i + 1 + (j + 1) * sizeY] + matrix[i + j * sizeY] + matrix[i + 1 + (j - 1) * sizeY] + matrix[i + (j - 1) * sizeY] + matrix[i - 1 + (j - 1) * sizeY] + matrix[i - 1 + j * sizeY]) / 8.0;
							continue;
						}
					}
				}
				free(matrix);
				matrix = aa;
				aa = (vec3 *) malloc(sizeof(vec3) * sizeX * sizeY);
			}
		}
		if (EXPOSURE_CONTROL){
			#pragma omp parallel for default(none) shared(color, matrix, sizeY) private(i, j) nowait
			for(int j = 0; j < sizeY; j++){
				for(int i = 0; i < sizeX; i++){
					color.rgbRed = (1.0f - expf(matrix[i + j * sizeY][0] * EXPOSURE)) * 255.;
					color.rgbGreen = (1.0f - expf(matrix[i + j * sizeY][1] * EXPOSURE)) * 255.;
					color.rgbBlue =  (1.0f - expf(matrix[i + j * sizeY][2] * EXPOSURE)) * 255.;
					FreeImage_SetPixelColor(bitmap, i , j , &color);
				}
			}
		} else{
			for(int j = 0; j < sizeY; j++){
				for(int i = 0; i < sizeX; i++){
					color.rgbRed = min((float)matrix[i + j * sizeY][0],1.0f) * 255.;
					color.rgbGreen = min((float)matrix[i + j * sizeY][1],1.0f) * 255.;
					color.rgbBlue = min((float)matrix[i + j * sizeY][2],1.0f) * 255.;
					FreeImage_SetPixelColor(bitmap, i , j , &color);
				}
			}
		}
		free(aa);
		free(matrix);
	}
Beispiel #5
0
static int
write_img(char *name, const greyscale_image *img) {
  FIBITMAP *image;
  RGBQUAD aPixel;
  int i,j;

  image = FreeImage_Allocate(img->width, img->height, 24, 0, 0, 0);
  if(!image) {
    perror("FreeImage_Allocate");
    return -1;
  }
  for(i = 0; i < img->height; i++) {
    for(j = 0; j < img->width; j++) {
      float v = img->v[i*img->width + j];
      if (v > 1.0) v = 1.0;
      else if (v < 0) v = 0.0;
      v *= 255.0;

      aPixel.rgbRed = (unsigned char) v;
      aPixel.rgbGreen = (unsigned char) v;
      aPixel.rgbBlue = (unsigned char) v;

      FreeImage_SetPixelColor(image, j, i, &aPixel);
    }
  }
  if(!FreeImage_Save(FIF_JPEG, image, name, 0)) {
    perror("FreeImage_Save");
  }
  FreeImage_Unload(image);

  return 0;
}
Beispiel #6
0
void Film::output(string path){
  int maxIntensity = 255;
  int bpp = 24;
  RGBQUAD color;
  FreeImage_Initialise();
  FIBITMAP* bitmap = FreeImage_Allocate(sceneWidth,
					sceneHeight,
					bpp);
  for(int h = 0; h < sceneHeight; h++){
    vector<Color> row = pixelData[h];
    for(int w = 0; w < sceneWidth; w++){
      Color pixelColor = row[w];
      color.rgbRed = pixelColor.getR() * maxIntensity;
      color.rgbGreen = pixelColor.getG() * maxIntensity;
      color.rgbBlue = pixelColor.getB() * maxIntensity;
      FreeImage_SetPixelColor(bitmap, w, h, &color);
    }
  }
  if (FreeImage_Save(FIF_PNG, bitmap, path.c_str(), 0)) {
    cout << "Image saved to " << path << endl;
    cout << sceneWidth << endl;
  }
  else {
    cerr << "Couldn't save image to " << path << endl;
    exit(1);
  }

  FreeImage_DeInitialise();
}
Beispiel #7
0
bool SaveTextureToFile(const char* filename, const void* data,  int w, int h)
{
	bool ret = false;
	FIBITMAP* bitmap = nullptr;

	bitmap = FreeImage_AllocateT(FIT_BITMAP, w, h, 32);
	CHECK(bitmap);

	RGBQUAD dst;
	const Color* imageData = (const Color*)data;
	for (int y = 0; y < h; ++y)
	{
		for (int x = 0; x < w; ++x)
		{
			const Color& src = imageData[((h - 1 - y) * w + x)];
			dst.rgbBlue = (BYTE)(src.b * 255);
			dst.rgbGreen = (BYTE)(src.g * 255);
			dst.rgbRed = (BYTE)(src.r * 255);
			dst.rgbReserved = 255;
			CHECK(FreeImage_SetPixelColor(bitmap, x, y, &dst));
		}
	}

	CHECK(FreeImage_Save(FIF_BMP, bitmap, filename, BMP_DEFAULT));

	ret = true;
Exit0:
	if (bitmap)
		FreeImage_Unload(bitmap);
	return ret;
}
bool process_image(std::string infile, std::string outfile, double brightness, double gamma)
{
	DIR *editdir = opendir("img/edit");
	struct dirent *file;
	while ((file = readdir(editdir)) != NULL)
	{
		if (strcmp(file -> d_name, outfile.c_str()) == 0)
		{
			return false;
		}
	}
	closedir(editdir);
	infile = "img/" + infile;
	outfile = "img/edit/" + outfile;
	FIBITMAP *input = FreeImage_Load(FIF_PNG, infile.c_str());
	if (input == NULL)
	{
		std::cerr << "Failed to load " << infile << std::endl;
		exit(1);
	}
	if (!FreeImage_Save(FIF_PNG, input, outfile.c_str()))
	{
		FreeImage_Unload(input);
		std::cerr << "Failed to save " << outfile << std::endl;
		exit(1);
	}
	FreeImage_Unload(input);
	FIBITMAP *output = FreeImage_Load(FIF_PNG, outfile.c_str());
	if (output == NULL)
	{
		std::cerr << "Failed to load " << outfile << std::endl;
		exit(1);
	}
	unsigned int img_w = FreeImage_GetWidth(output);
	unsigned int img_h = FreeImage_GetHeight(output);
	RGBQUAD pixel;
	for (unsigned int x = 0; x < img_w; x++)
	{
		for (unsigned int y = 0; y < img_h; y++)
		{
			FreeImage_GetPixelColor(output, x, y, &pixel);
			pixel.rgbRed = int(clamp(0, pixel.rgbRed * brightness, 255));
			pixel.rgbBlue = int(clamp(0, pixel.rgbBlue * brightness, 255));
			pixel.rgbGreen = int(clamp(0, pixel.rgbGreen * brightness, 255));
			pixel.rgbRed = int(clamp(0, pow(((double) pixel.rgbRed) / 255.0f, gamma) * 255.0, 255));
			pixel.rgbBlue = int(clamp(0, pow(((double) pixel.rgbBlue) / 255.0f, gamma) * 255.0, 255));
			pixel.rgbGreen = int(clamp(0, pow(((double) pixel.rgbGreen) / 255.0f, gamma) * 255.0, 255));
			FreeImage_SetPixelColor(output, x, y, &pixel);
		}
	}
	if (!FreeImage_Save(FIF_PNG, output, outfile.c_str()))
	{
		FreeImage_Unload(input);
		std::cerr << "Failed to save " << outfile << std::endl;
		exit(1);
	}
	FreeImage_Unload(output);
	return true;
}
  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);
      }
  }
static bool mergeBitBltToRGBA(FIBITMAP *image, const std::string &pathToMask)
{
    if(!image)
        return false;

    if(!Files::fileExists(pathToMask))
        return false; //Nothing to do

    FIBITMAP *mask = loadImage(pathToMask);

    if(!mask)
        return false;//Nothing to do

    unsigned int img_w  = FreeImage_GetWidth(image);
    unsigned int img_h  = FreeImage_GetHeight(image);
    unsigned int mask_w = FreeImage_GetWidth(mask);
    unsigned int mask_h = FreeImage_GetHeight(mask);

    RGBQUAD Fpix;
    RGBQUAD Bpix;
    RGBQUAD Npix = {0x0, 0x0, 0x0, 0xFF};

    for(unsigned int y = 0; (y < img_h) && (y < mask_h); y++)
    {
        for(unsigned int x = 0; (x < img_w) && (x < mask_w); x++)
        {

            FreeImage_GetPixelColor(image, x, y, &Fpix);
            FreeImage_GetPixelColor(mask, x, y, &Bpix);

            Npix.rgbRed     = ((0x7F & Bpix.rgbRed) | Fpix.rgbRed);
            Npix.rgbGreen   = ((0x7F & Bpix.rgbGreen) | Fpix.rgbGreen);
            Npix.rgbBlue    = ((0x7F & Bpix.rgbBlue) | Fpix.rgbBlue);
            int newAlpha = 255 -
                           ((int(Bpix.rgbRed) +
                             int(Bpix.rgbGreen) +
                             int(Bpix.rgbBlue)) / 3);
            if((Bpix.rgbRed > 240u) //is almost White
               && (Bpix.rgbGreen > 240u)
               && (Bpix.rgbBlue > 240u))
                newAlpha = 0;

            newAlpha = newAlpha + ((int(Fpix.rgbRed) +
                                    int(Fpix.rgbGreen) +
                                    int(Fpix.rgbBlue)) / 3);
            if(newAlpha > 255)
                newAlpha = 255;
            Npix.rgbReserved = newAlpha;

            FreeImage_SetPixelColor(image, x, y, &Npix);
        }
    }
    FreeImage_Unload(mask);
    return true;
}
Beispiel #11
0
int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		printf("Usage : cworld2img input_filename.bin output_filename.png\n\n");
		return 0;
	}
	FreeImage_Initialise();
	FIBITMAP *bitmap = FreeImage_Allocate(WORLD_WIDTH, WORLD_HEIGHT, 32);
	if(!bitmap)
	{
		printf("Error while allocating image. Aborting");
		return -1;
	}
	FILE *fd = fopen(argv[1], "rb");
	fread(c_world.solids, sizeof(block), WORLD_HEIGHT * WORLD_WIDTH, fd);
	fclose(fd);
	for(int i = 0; i < WORLD_HEIGHT; i++)
	{
		for(int j = 0; j < WORLD_WIDTH; j++)
		{
			switch(c_world.solids[WORLD_WIDTH * i + j])
			{
			case BLCK_AIR:
				FreeImage_SetPixelColor(bitmap, j, WORLD_HEIGHT - i, &qpixel_air);break;
			case BLCK_DIRT:
				FreeImage_SetPixelColor(bitmap, j, WORLD_HEIGHT - i, &qpixel_dirt);break;
			default:
				FreeImage_SetPixelColor(bitmap, j, WORLD_HEIGHT - i, &qpixel_unknown);break;
			}
		}
	}
	if(!FreeImage_Save(FIF_PNG, bitmap, argv[2], 0))
	{
		printf("Error while saving image. Aborting");
		return -1;
	}
	FreeImage_DeInitialise();
	return 0;
}
static void splitRGBAtoBitBlt(FIBITMAP * &image, FIBITMAP *&mask)
{
    unsigned int img_w   = FreeImage_GetWidth(image);
    unsigned int img_h   = FreeImage_GetHeight(image);

    mask = FreeImage_AllocateT(FIT_BITMAP,
                               img_w, img_h,
                               FreeImage_GetBPP(image),
                               FreeImage_GetRedMask(image),
                               FreeImage_GetGreenMask(image),
                               FreeImage_GetBlueMask(image));

    RGBQUAD Fpix;
    RGBQUAD Npix = {0x0, 0x0, 0x0, 0xFF};

    for(unsigned int y = 0; (y < img_h); y++)
    {
        for(unsigned int x = 0; (x < img_w); x++)
        {
            FreeImage_GetPixelColor(image, x, y, &Fpix);

            uint8_t grey = (255 - Fpix.rgbReserved);
            Npix.rgbRed  = grey;
            Npix.rgbGreen= grey;
            Npix.rgbBlue = grey;
            Npix.rgbReserved = 255;

            Fpix.rgbRed  = subtractAlpha(Fpix.rgbRed, grey);
            Fpix.rgbGreen= subtractAlpha(Fpix.rgbGreen, grey);
            Fpix.rgbBlue = subtractAlpha(Fpix.rgbBlue, grey);
            Fpix.rgbReserved = 255;

            FreeImage_SetPixelColor(image, x, y, &Fpix);
            FreeImage_SetPixelColor(mask,  x, y, &Npix);
        }
    }
}
Beispiel #13
0
void Generate_thread(FIBITMAP* bitmap, Camera camera,int init_num, int thread_num) {
	for (int i = init_num; i < Width; i += thread_num) {
		cout << i << endl;
		for (int j = 0; j < Height; j++) {
			RGBQUAD color;
			vec3 mycolor;
			Ray ray = camera.GenerateRay(vec2(i, j));
			mycolor = Trace(ray);
			color.rgbRed = mycolor.x * 255;
			color.rgbGreen = mycolor.y * 255;
			color.rgbBlue = mycolor.z * 255;
			FreeImage_SetPixelColor(bitmap, i, j, &color);
		}
	}
}
void saveImage(const char* _fileName, unsigned char* _image, int _width, int _height)
{
	FIBITMAP* resultImage = FreeImage_Allocate(_width, _height, 24);

	for(int y = 1; y <= _height; ++y)
		for(int x = 0; x < _width; ++x)
		{
			int color = *_image;
			color = (color << 8) | (color << 16) | (color) | (color << 24);
			FreeImage_SetPixelColor(resultImage, x, _height - y, (RGBQUAD*)(&color));
			++_image;
		}

	FreeImage_Save(FIF_BMP, resultImage, _fileName);
}
Beispiel #15
0
void ThinLens::render_scene(World& w) {
	RGBColor L;
	Ray ray;
	ViewPlane vp(w.vp);
	FreeImage_Initialise();
	FIBITMAP* bitmap = FreeImage_Allocate(vp.hres, vp.vres, 24);
	RGBQUAD color;
	int depth = 0;

	Point2D sp;
	Point2D pp;
	Point2D dp;
	Point2D lp;

	vp.s /= zoom;

	for(int r = 0; r < vp.vres; r++)
		for(int c = 0 ; c < vp.hres; c++) {
			L = black;

			for(int n = 0; n < vp.num_samples; n++) {
				sp = vp.sampler_ptr -> sample_unit_square();
				pp.x = vp.s * (c - vp.hres / 2.0 + sp.x);
				pp.y = vp.s * (r - vp.vres / 2.0 + sp.y);

				dp = sampler_ptr -> sample_unit_disk();
				lp = dp * lens_radius;

				ray.o = eye + lp.x * u + lp.y * v;
				ray.d = ray_direction(pp, lp);
				L += w.tracer_ptr -> trace_ray(ray);
			}

			L /= vp.num_samples;
			L *= exposure_time;
			w.display_pixel(r, c, L);
			color.rgbRed = (int)(L.r*255);
			color.rgbGreen = (int)(L.g*255);
			color.rgbBlue = (int)(L.b*255);
			FreeImage_SetPixelColor(bitmap, c, r, &color);
		}
	if (FreeImage_Save(FIF_PNG, bitmap, "test.png", 0))
		std::cout << "Image Successfully Saved!" << std::endl;

	FreeImage_DeInitialise();

}
void painter::paint(string file, lattice::phenotypes::phenotype const& phenotype, string path)
{
	FIBITMAP *bitmap = FreeImage_Allocate(
		phenotype.get_width() * SCALEFACTOR, phenotype.get_height() * SCALEFACTOR, BPP);
	RGBQUAD color;

	auto& cells = phenotype.expose_cells();
	vector<polygon> sc_polys;
	for (auto& cell : cells)
	{
		lattice::rgb cellColor;
		polygon cellPoly = cell->get_geometry(), scaled;
		boost::geometry::strategy::transform::scale_transformer<double, 2, 2> scale(static_cast<double>(SCALEFACTOR));
		boost::geometry::transform(cellPoly, scaled, scale);
		sc_polys.push_back(scaled);

		boost::geometry::model::box<point> box;
		boost::geometry::envelope(scaled, box);
		for (unsigned int y = static_cast<unsigned int>(box.min_corner().get<1>());
			y <= box.max_corner().get<1>(); ++y)
		{
			for (unsigned int x = static_cast<unsigned int>(box.min_corner().get<0>());
				x <= box.max_corner().get<0>(); ++x)
			{
				boost::geometry::model::d2::point_xy<double> p(x, y);
				if (!boost::geometry::covered_by(p, scaled)) continue;
				cellColor = cell->get_state().color;

				color.rgbRed = cellColor.r;
				color.rgbGreen = cellColor.g;
				color.rgbBlue = cellColor.b;
				FreeImage_SetPixelColor(bitmap, x, y, &color);
			}
		}
	}

	for (auto& poly : sc_polys) rasterize_polygon_border(bitmap, poly);

	string fullPath = path + "/";
	boost::filesystem::create_directory(fullPath);
	FIBITMAP *scaled = FreeImage_Rescale(bitmap, DESIRED_WIDTH, DESIRED_HEIGHT, FILTER_BOX);
	FreeImage_Save(FIF_PNG, scaled, (fullPath + file).c_str(), 0);

	FreeImage_Unload(bitmap);
	FreeImage_Unload(scaled);
}
Beispiel #17
0
    void PImage::save(const char * out) {
        FIBITMAP *bitmap = FreeImage_Allocate(width, height, 24);
        RGBQUAD c;
        if (!bitmap) exit(1);

        for(int y=0; y<height; y++) {
            for(int x=0; x<width; x++) {
                c.rgbRed    = texturebuffer[(((y*width)+x)*4)+0];
                c.rgbGreen  = texturebuffer[(((y*width)+x)*4)+1];
                c.rgbBlue   = texturebuffer[(((y*width)+x)*4)+2];
                FreeImage_SetPixelColor(bitmap, x, y, &c);
            }
        }

        FreeImage_Save(FIF_PNG, bitmap, out, 0);
        FreeImage_Unload(bitmap);
    }
Beispiel #18
0
void Fisheye::render_scene(World& w) {
	RGBColor L;
	ViewPlane vp(w.vp);
	FreeImage_Initialise();
	FIBITMAP* bitmap = FreeImage_Allocate(vp.hres, vp.vres, 24);
	RGBQUAD color;
	int hres = vp.hres;
	int vres = vp.vres;
	float s = vp.s;
	Ray ray;
	int depth = 0;
	Point2D sp;
	Point2D pp;
	float r_squared;

	ray.o  = eye;

	for(int r = 0; r < vres; r++)
		for(int c = 0; c < hres; c++) {
			L = black;

			for(int j = 0; j < vp.num_samples; j++) {
				sp = vp.sampler_ptr -> sample_unit_square();
				pp.x = s * (c - hres / 2.0 + sp.x);
				pp.y = s * (r - vres / 2.0 + sp.y);
				ray.d = ray_direction(pp, hres, vres, s, r_squared);

				if(r_squared <= 1.0)
					L += w.tracer_ptr -> trace_ray(ray);
			}

			L /= vp.num_samples;
			L *= exposure_time;
			w.display_pixel(r, c, L);
			color.rgbRed = (int)(L.r*255);
			color.rgbGreen = (int)(L.g*255);
			color.rgbBlue = (int)(L.b*255);
			FreeImage_SetPixelColor(bitmap, c, r, &color);
		}
	if (FreeImage_Save(FIF_PNG, bitmap, "test.png", 0))
		std::cout << "Image Successfully Saved!" << std::endl;
	FreeImage_DeInitialise();
}
//write_img
void write_img(char *name, pixel *data, int width, int height) {
	FIBITMAP *image;
	RGBQUAD aPixel;
	int i, j;

	image = FreeImage_Allocate(width, height, 24, 0, 0, 0);
	if (!image) {
		perror("FreeImage_Allocate");
		return;
	}
	for (i = 0; i < height; i++) {
		for (j = 0; j < width; j++) {
			aPixel.rgbRed = data[i*width + j].r;
			aPixel.rgbGreen = data[i*width + j].g;
			aPixel.rgbBlue = data[i*width + j].b;

			FreeImage_SetPixelColor(image, j, i, &aPixel);
		}
	}
	if (!FreeImage_Save(FIF_TIFF, image, name, 0)) {
		perror("FreeImage_Save");
	}
	FreeImage_Unload(image);
}//write_img
Beispiel #20
0
void *process_thread(void *data)
{
	struct thread_data *args;
	args = (struct thread_data*) data;
	std::queue<std::string> *input = args -> input;
	std::mutex *lock = args -> lock;
	double brightness = args -> brightness;
	double gamma = args -> gamma;
	std::string infile;
	std::string outfile;
	bool exists;
	while (true)
	{
		exists = false;
		while (!(lock -> try_lock()));
		if (input -> empty())
		{
			lock -> unlock();
			break;
		}
		infile = input -> front();
		input -> pop();
		lock -> unlock();
		gen_edit_filename(infile, outfile);
		DIR *editdir = opendir("img/edit");
		struct dirent *file;
		while ((file = readdir(editdir)) != NULL)
		{
			if (strcmp(file -> d_name, outfile.c_str()) == 0)
			{
				exists = true;
				break;
			}
		}
		closedir(editdir);
		infile = "img/" + infile;
		outfile = "img/edit/" + outfile;
		if (exists) { continue; }
		else
		{
			while (!(lock -> try_lock()));
			std::cout << "Processing " << infile << std::endl;
			lock -> unlock();
		}
		FIBITMAP *input = FreeImage_Load(FIF_PNG, infile.c_str());
		if (input == NULL)
		{
			while (!(lock -> try_lock()));
			std::cerr << "Failed to load " << infile << std::endl;
			lock -> unlock();
			exit(1);
		}
		if (!FreeImage_Save(FIF_PNG, input, outfile.c_str()))
		{
			FreeImage_Unload(input);
			while (!(lock -> try_lock()));
			std::cerr << "Failed to save " << outfile << std::endl;
			lock -> unlock();
			exit(1);
		}
		FreeImage_Unload(input);
		FIBITMAP *output = FreeImage_Load(FIF_PNG, outfile.c_str());
		if (output == NULL)
		{
			while (!(lock -> try_lock()));
			std::cerr << "Failed to load " << outfile << std::endl;
			lock -> unlock();
			exit(1);
		}
		unsigned int img_w = FreeImage_GetWidth(output);
		unsigned int img_h = FreeImage_GetHeight(output);
		RGBQUAD pixel;
		for (unsigned int x = 0; x < img_w; x++)
		{
			for (unsigned int y = 0; y < img_h; y++)
			{
				FreeImage_GetPixelColor(output, x, y, &pixel);
				pixel.rgbRed = int(clamp(0, pixel.rgbRed * brightness, 255));
				pixel.rgbBlue = int(clamp(0, pixel.rgbBlue * brightness, 255));
				pixel.rgbGreen = int(clamp(0, pixel.rgbGreen * brightness, 255));
				pixel.rgbRed = int(clamp(0, pow(((double) pixel.rgbRed) / 255.0f, gamma) * 255.0, 255));
				pixel.rgbBlue = int(clamp(0, pow(((double) pixel.rgbBlue) / 255.0f, gamma) * 255.0, 255));
				pixel.rgbGreen = int(clamp(0, pow(((double) pixel.rgbGreen) / 255.0f, gamma) * 255.0, 255));
				FreeImage_SetPixelColor(output, x, y, &pixel);
			}
		}
		if (!FreeImage_Save(FIF_PNG, output, outfile.c_str()))
		{
			FreeImage_Unload(input);
			while (!(lock -> try_lock()));
			std::cerr << "Failed to save " << outfile << std::endl;
			lock -> unlock();
			exit(1);
		}
		FreeImage_Unload(output);
		while (!(lock -> try_lock()));
		std::cout << "Saved " << outfile << std::endl;
		lock -> unlock();
	}
	pthread_exit(NULL);
}
Beispiel #21
0
BOOL fipImage::setPixelColor(unsigned x, unsigned y, RGBQUAD *value) {
	_bHasChanged = TRUE;
	return FreeImage_SetPixelColor(_dib, x, y, value);
}
Beispiel #22
0
void TileManager::ProcessTileMap(std::string a_sFileName)
{
	m_sCurrentLevel = a_sFileName;
	int rows = m_pBaseSprite[a_sFileName]->GetHeight() / TILE_HEIGHT;
	int columns = m_pBaseSprite[a_sFileName]->GetWidth() / TILE_WIDTH;
	int idCounter = 0;
	
	int id = 0;

	int counter = 0;
	
	for(int row = 0; row < rows; row++)
	{
		for(int col = 0; col < columns; col++)
		{
			Tmpl8::Surface* surface = new Tmpl8::Surface(TILE_WIDTH, TILE_HEIGHT);
			m_pBaseSprite[a_sFileName]->CopyPartTo(surface, 0, 0, col * TILE_WIDTH, row * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);

			if(row == 0 && col == 0)
			{
				TileNode* tileNode = new TileNode(row, col, 0);
				m_pTiles[a_sFileName].push_back(tileNode);
				m_pTileSurfaces[a_sFileName].push_back(new TileSurface(idCounter,surface));
				tileNode->SetSurface(tileNode->m_iTileId);
				counter++;
				idCounter++;
				continue;
			}
			bool isUnique = true;
			for(std::vector<TileSurface*>::iterator iter = m_pTileSurfaces[a_sFileName].begin(); iter != m_pTileSurfaces[a_sFileName].end();)
			{
				if(!(*iter)->CompareSurfaces(surface))
				{
					isUnique = false;
					id = (*iter)->m_iTileId;
					iter = m_pTileSurfaces[a_sFileName].end();
				}
				else
				{
					iter++;
				}
			}

			if(isUnique)
			{
				m_pTileSurfaces[a_sFileName].push_back(new TileSurface(idCounter,surface));
				id = idCounter;
				idCounter++;
			}
			else
			{
				delete surface;
			}
			TileNode* tileNode = new TileNode(row, col, id);
			m_pTiles[a_sFileName].push_back(tileNode);
			tileNode->SetSurface(tileNode->m_iTileId);
			counter++;
		}
	}
	FIBITMAP* bitmap = FreeImage_Allocate(512, 1024, 24);
	int tilesInRow = 512 / TILE_WIDTH;
	int rowCounter = 0;
	int colCounter = 0;
	for(std::vector<TileSurface*>::iterator iter = m_pTileSurfaces[a_sFileName].begin(); iter != m_pTileSurfaces[a_sFileName].end(); iter++)
	{
		Tmpl8::Pixel* buffer = (*iter)->m_pTileSurface->GetBuffer();
		int pitch = (*iter)->m_pTileSurface->GetPitch();

		for(int x = 0; x < TILE_WIDTH; x++)
		{
			for(int y = 0; y < TILE_HEIGHT; y++)
			{
				RGBQUAD color;
				color.rgbRed = (buffer[x + y*pitch] & 0xFF0000) >> 16;
				color.rgbGreen = (buffer[x + y*pitch] & 0x00FF00) >> 8;
				color.rgbBlue = buffer[x + y*pitch] & 0x0000FF;
				FreeImage_SetPixelColor(bitmap, colCounter*TILE_WIDTH + x, 1023 - rowCounter*TILE_HEIGHT - y, &color);
			}
		}
		colCounter++;
		if(colCounter >= tilesInRow)
		{
			colCounter = 0;
			rowCounter++;
		}
	}
	FreeImage_Save(FIF_PNG, bitmap, std::string("assets/tilesets/"+a_sFileName+"_tilemap.png").c_str(), 0);

	std::string tileMap;
	std::stringstream ss;
			
	counter = 0;
	for(int row = 0; row < rows; row++)
	{
		for(int col = 0; col < columns; col++)
		{
			TileNode* currentNode = m_pTiles[a_sFileName][counter];
			counter++;

			ss.str("");
			ss << currentNode->m_iTileId;
			tileMap += ss.str();

			if(col+1 != columns)
				tileMap += ",";
		}
		
		if(row+1 != rows)
			tileMap += "\n";
	}
	std::ofstream tilemapFile;
	tilemapFile.open (std::string("assets/tilesets/"+a_sFileName+".dat").c_str());
	tilemapFile << tileMap;
	tilemapFile.close();
	std::ofstream metaFile;
	metaFile.open (std::string("assets/tilesets/"+a_sFileName+"_metadata.dat").c_str());
	ss.str("");
	ss << m_pTileSurfaces[a_sFileName].size() << "," << TILE_WIDTH << "," << TILE_HEIGHT << "," << m_pBaseSprite[a_sFileName]->GetWidth() << "," << m_pBaseSprite[a_sFileName]->GetHeight();
	metaFile << ss.str();
	metaFile.close();
	
	for(std::vector<TileSurface*>::iterator iter = m_pTileSurfaces[a_sFileName].begin(); iter != m_pTileSurfaces[a_sFileName].end(); iter++)
	{
		delete *iter;
	}
	m_pTileSurfaces[a_sFileName].clear();
	for(std::vector<TileNode*>::iterator iter = m_pTiles[a_sFileName].begin(); iter != m_pTiles[a_sFileName].end(); iter++)
	{
		delete *iter;
	}
	m_pTiles[a_sFileName].clear();
	delete m_pBaseSprite[a_sFileName];
}
Beispiel #23
0
/**
 * This method sets the color on the given position.
 *
 * @param ulX the horizontal (x) position, on which to set the color
 * @param ulY the vertical (y) position, on which to set the color
 * @param colorValue a pointer to the color value field to set
 * @return true if pixel color was set, else false
 */
bool fipImage::setPixelColor( const unsigned long ulX, const unsigned long ulY,
		RGBQUAD * colorValue ){
	
	return FreeImage_SetPixelColor( pImageData, ulX, ulY, colorValue );
}
Beispiel #24
0
void Image::setPixel(RGBQUAD &rgb, int x, int y) const {
	FreeImage_SetPixelColor(m_fiImage, x, y, &rgb);
}
void CFontTexCreaterDlg::OnBnClickedButton1()
{
	int texW = 2048 ;
	int texH = 2048 ;

	FILE* pF = fopen( "FontBuf" , "rb" ) ;
	fseek( pF , 0 , SEEK_END ) ;

	DWORD fileSz = ftell( pF ) ;

	char *bf = new char[ fileSz ] ;

	fseek( pF , 0 , SEEK_SET ) ;
	fread( bf , fileSz , 1 , pF ) ;

	if( fileSz == 1024 * 1024 )
	{
		texW = 1024 ;
		texH = 1024 ;
	}
	else if( fileSz == 2048 * 1024 )
	{
		texW = 1024 ;
		texH = 2048 ;
	}
	else if( fileSz == 2048 * 2048 )
	{
		texW = 2048 ;
		texH = 2048 ;
	}
	else
	{
		::MessageBoxA( NULL , "FontBuf's size is wrong." , "" , MB_OK ) ;
	}

	fclose( pF ) ;

	//
	{
		FreeImage_Initialise() ;

		FIBITMAP* bm = FreeImage_Allocate( texW , texH , 24 ) ;

		RGBQUAD clr ;

		for( int y = 0 ; y < texH ; y ++ )
		{
			for( int x = 0 ; x < texW ; x ++ )
			{
				char val = bf[ y * texW + x ] ;

				clr.rgbBlue = val ;
				clr.rgbGreen = val ;
				clr.rgbRed = val ;
				clr.rgbReserved = 255 ;

				FreeImage_SetPixelColor( bm , x , texH - 1 - y , &clr ) ;
			}
		}

		FreeImage_Save( FIF_BMP , bm , "FontBuf.bmp" ) ;

		FreeImage_Unload( bm ) ;

		FreeImage_DeInitialise() ;
	}
}
void Image_Output()
{	
	/*
	FreeImage_Initialise();	
	FIBITMAP *m_image = FreeImage_Allocate( M * W - 1, M * H - 1, 24 );		  
	struct tagRGBQUAD rgbquad;
	
	for ( int i = 0; i < M * H - 1; ++i )
	{
		for ( int j = 0; j < M * W - 1; ++j )
		{					
			rgbquad.rgbRed   = o_image[i][j].r;						
			rgbquad.rgbGreen = o_image[i][j].g;			
			rgbquad.rgbBlue  = o_image[i][j].b;				  				  
			FreeImage_SetPixelColor( m_image, j, i, &rgbquad );				  
		}
	}
		  
	FreeImage_Save( FIF_BMP, m_image, o_file, BMP_DEFAULT );		
	FreeImage_DeInitialise();
	*/

	FreeImage_Initialise();	
	FIBITMAP *m_image = FreeImage_Allocate( M * W, M * H, 24 );		  
	struct tagRGBQUAD rgbquad;
	
	for ( int i = 0; i < M * H; ++i )
	{
		for ( int j = 0; j < M * W; ++j )
		{					
			if ( i == ( M * H - 1 ) || j == ( M * W - 1 ) )
			{
				int u = 0, v = 0;

				if ( i == ( M * H - 1 ) )
				{
					u = -1;	
				}
		
				if ( j == ( M * W - 1 ) )
				{
					v = -1;
				}

				rgbquad.rgbRed   = o_image[i+u][j+v].r;						
				rgbquad.rgbGreen = o_image[i+u][j+v].g;			
				rgbquad.rgbBlue  = o_image[i+u][j+v].b;				  				  
				FreeImage_SetPixelColor( m_image, j, i, &rgbquad );				  
			}
			else
			{			
				rgbquad.rgbRed   = o_image[i][j].r;						
				rgbquad.rgbGreen = o_image[i][j].g;			
				rgbquad.rgbBlue  = o_image[i][j].b;				  				  
				FreeImage_SetPixelColor( m_image, j, i, &rgbquad );				  
			}
		}
	}
		  
	FreeImage_Save( FIF_BMP, m_image, o_file, BMP_DEFAULT );		
	FreeImage_DeInitialise();
}
Beispiel #27
0
bool IPLFileIO::saveFile(const std::string path, IPLImage* image, int format, int flags, IPLImage* result, bool preview)
{
    int width = image->width();
    int height = image->height();

    FIBITMAP *dib = FreeImage_Allocate(width, height, 24);

    if(image->type() == IPLData::IMAGE_COLOR)
    {
        for(int y = 0; y < height; y++)
        {
            for(int x = 0; x < width; x++)
            {
                RGBQUAD rgb;
                rgb.rgbRed      = static_cast<BYTE>(image->plane(0)->p(x, y) * FACTOR_TO_UCHAR); // R
                rgb.rgbGreen    = static_cast<BYTE>(image->plane(1)->p(x, y) * FACTOR_TO_UCHAR); // G
                rgb.rgbBlue     = static_cast<BYTE>(image->plane(2)->p(x, y) * FACTOR_TO_UCHAR); // B
                FreeImage_SetPixelColor(dib, x, y, &rgb);
            }
        }
    }
    else
    {
        for(int y = 0; y < height; y++)
        {
            for(int x = 0; x < width; x++)
            {
                unsigned char value = image->plane(0)->p(x, y) * FACTOR_TO_UCHAR;
                RGBQUAD rgb;
                rgb.rgbRed      = value; // R
                rgb.rgbGreen    = value; // G
                rgb.rgbBlue     = value; // B
                FreeImage_SetPixelColor(dib, x, y, &rgb);
            }
        }
    }

    // all files need to be flipped
    FreeImage_FlipVertical(dib);

    bool success = false;

    if(preview)
    {
        // only save to memory for preview
        FIMEMORY* hmem = NULL;
        // open and allocate a memory stream
        hmem = FreeImage_OpenMemory();

        success = FreeImage_SaveToMemory((FREE_IMAGE_FORMAT)format, dib, hmem, flags) != 0;

        // write to result
        if(result)
        {
            loadMemory((void*)hmem, result);
        }

        //FreeImage_CloseMemory(hmem);

    }
    else
    {
        // actually save file
        success = FreeImage_Save((FREE_IMAGE_FORMAT)format, dib, path.c_str(), flags) != 0;

        // write to result
        if(result)
        {
            std::string information;
            loadFile(path, result, information);
        }
    }


    // free temporary memory
    FreeImage_Unload(dib);

    return success;
}
Beispiel #28
0
bool Image::load (const char* fname)
{
	release () ;

//	createTestData () ;
//	return true ;

	char buf[256] ;
	sprintf_s (buf, sizeof (buf), "image\\%s", fname) ;
//	fname = "image\\avatar000.png" ;

	FILE* pFile = NULL ;
	fopen_s (&pFile, buf, "rb") ;
	if (pFile == NULL)
		return false ;

	FreeImageIO io;

	io.read_proc  = myReadProc;
	io.write_proc = myWriteProc;
	io.seek_proc  = mySeekProc;
	io.tell_proc  = myTellProc;

	// find the buffer format
	FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromHandle(&io, (fi_handle)pFile, 0);

	if(fif == FIF_UNKNOWN) 
	{
	   /* Close the file */
		fclose(pFile);
		return false ;
	}

	// load from the file handle
	FIBITMAP *dib = FreeImage_LoadFromHandle(fif, &io, (fi_handle)pFile, 0);
		
	BYTE* pPixelData = FreeImage_GetBits(dib) ;

	int width, height,pitch  ;
	width =  FreeImage_GetWidth(dib);
	height = FreeImage_GetHeight(dib);
	pitch = FreeImage_GetPitch(dib);
	int bpp = FreeImage_GetBPP(dib) ;
	assert (bpp == 32) ;

	FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib) ;
	assert (image_type == FIT_BITMAP) ;

//	/*
	//轉換rgba(因為rgba,的順序不同)
	RGBQUAD rgba ;
	BYTE* pBit = pPixelData ;
	for (int i = 0 ; i<height; i++)
	{
		BYTE* pPixel = pBit ;
		for (int m = 0; m<width; m++)
		{
			if (FreeImage_GetPixelColor(dib, m, i, &rgba))
			{
				BYTE tmp = rgba.rgbBlue ;
				rgba.rgbBlue = rgba.rgbRed ;
				rgba.rgbRed = tmp ;
				FreeImage_SetPixelColor (dib, m, i, &rgba) ;
			}
		}
		pBit += pitch ;
	}
//			*/

//---------------------------------------------------
   //把pixel copy給
   //最大記憶體
	if (pPixelData != NULL)
	{
		assert (textureID == NO_TEXTURE_ID) ;
		if (textureID == NO_TEXTURE_ID)
		{
			//空的要先建立
			// Allocates one texture handle
			glGenTextures(1, &textureID);
		}

		assert (textureID != NO_TEXTURE_ID) ;


		// Binds this texture handle so we can load the data into it
		glBindTexture(GL_TEXTURE_2D, textureID);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixelData);

		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

		// free the loaded FIBITMAP
		FreeImage_Unload(dib);
	}


	return true ;
}
int main(int argc, char** argv)
{
    if(argc < 2)
    {
        printf("Error! No Font Specified!\n");
        return 1;
    }
    std::string filename(argv[1]);
const size_t last_slash_idx = filename.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
    filename.erase(0, last_slash_idx + 1);
}

    // Remove extension if present.
    const size_t period_idx = filename.rfind('.');
    if (std::string::npos != period_idx)
    {
         filename.erase(period_idx);
    }

    FIBITMAP* bitmap = FreeImage_Allocate(4096, 4096, 32);

    FreeImage_SetTransparent(bitmap, true);
    FT_Library library;

    FT_Init_FreeType(&library);

    FT_Face face;

    FT_New_Face(library, argv[1], 0, &face);

    rapidjson::StringBuffer s;
    rapidjson::Writer<rapidjson::StringBuffer> writer(s);

    writer.StartObject();
    writer.String("glyphs");
    writer.StartArray();
    int tileSize = 64;
    int tileCount = 64;
    FT_Set_Pixel_Sizes(face, 0, tileSize);
    for (int c = 32, id = 0; c < 4096; ++c, ++id)
    {
        FT_Load_Char(face, c, FT_LOAD_RENDER);

        FT_Bitmap bmp = face->glyph->bitmap;

        FT_Glyph_Metrics metrics = face->glyph->metrics;

        int i = 0, j = 0;
        for (j = 0; j < bmp.rows; ++j)
        {
            for (i = 0; i < bmp.width; ++i)
            {
                RGBQUAD value = {bmp.buffer[j * bmp.width + i],
                                 bmp.buffer[j * bmp.width + i],
                                 bmp.buffer[j * bmp.width + i],
                                 bmp.buffer[j * bmp.width + i]};
                FreeImage_SetPixelColor(
                    bitmap, (id % tileCount) * tileSize + i,
                    (id / tileCount) * tileSize + bmp.rows - j, &value);
            }
        }

        double x = (id % tileCount) * tileSize;
        double y = (id / tileCount) * tileSize;

        writer.StartObject();
        {
            writer.String("id");
            writer.Uint(c);
            writer.String("char");
            writer.String((const char*)&c);
            writer.String("metrics");
            writer.StartObject();
            {
                writer.String("width");
                writer.Int(metrics.width / 64);
                writer.String("height");
                writer.Int(metrics.height / 64);
                writer.String("horiBearingX");
                writer.Int(metrics.horiBearingX / 64);
                writer.String("horiBearingY");
                writer.Int(metrics.horiBearingY / 64);
                writer.String("horiAdvance");
                writer.Int(metrics.horiAdvance / 64);
                writer.String("vertBearingX");
                writer.Int(metrics.vertBearingX / 64);
                writer.String("vertBearingY");
                writer.Int(metrics.vertBearingY / 64);
                writer.String("vertAdvance");
                writer.Int(metrics.vertAdvance / 64);
            }
            writer.EndObject();
            writer.String("uv");
            writer.StartArray();
            writer.StartArray();
            writer.Double(x / 4096.0);
            writer.Double((y - metrics.height / 64) / 4096.0);
            writer.EndArray();
            writer.StartArray();
            writer.Double(x / 4096.0);
            writer.Double(y / 4096.0);
            writer.EndArray();
            writer.StartArray();
            writer.Double((x + metrics.width / 64) / 4096.0);
            writer.Double(y / 4096.0);
            writer.EndArray();
            writer.StartArray();
            writer.Double((x + metrics.width / 64) / 4096.0);
            writer.Double((y - metrics.height / 64) / 4096.0);
            writer.EndArray();
            writer.EndArray();
        }
        writer.EndObject();
    }

    writer.EndArray();
    writer.EndObject();

    FILE* fp = fopen((filename + ".json").c_str(), "w");

    fputs(s.GetString(), fp);

    fclose(fp);

    if (FreeImage_Save(FIF_PNG, bitmap, (filename + ".png").c_str(), BMP_DEFAULT))
    {
        printf("Saved file to %s\n", (filename + ".png").c_str());
    }

    FreeImage_Unload(bitmap);

    return 0;
}