freetype使用文泉驿显示及保存图片

https://blog.csdn.net/zb774095236/article/details/94016538

 

https://blog.csdn.net/qq_32693119/article/details/79961312

gcc  example.c  -o  example -lfreetype -lm

1.使用开源库文泉驿字库

./example  wqy.ttc ni

https://blog.csdn.net/qq_22655017/article/details/90034431

例子支持中文

 

/* example1.c                                                      */
/*                                                                 */
/* This small program shows how to print a rotated string with the */
/* FreeType 2 library.                                             */


#include 
#include 
#include 
#include 
#include 
#include 
#include FT_FREETYPE_H





#define		USE_ICONV
#ifdef USE_ICONV
#include "iconv.h"
#endif
#define WIDTH   120
#define HEIGHT  30


/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];


/* Replace this function with something useful. */

void draw_bitmap(FT_Bitmap*  bitmap, FT_Int x, FT_Int y)
{
	FT_Int  i, j, p, q;
	FT_Int  x_max = x + bitmap->width;
	FT_Int  y_max = y + bitmap->rows;

	for ( i = x, p = 0; i < x_max; i++, p++ )
	{
		for ( j = y, q = 0; j < y_max; j++, q++ )
		{
			if ( i < 0 || j < 0 || i >= WIDTH || j >= HEIGHT ) {
				continue;
			}
			image[j][i] |= bitmap->buffer[q * bitmap->width + p];
		}
	}
}

void show_image(void)
{
	int  i, j;

	for ( i = 0; i < HEIGHT; i++ )
	{
		for ( j = 0; j < WIDTH; j++ ) {
			putchar(image[i][j] == 0 ? ' ' : image[i][j] < 128 ? '+' : '*');
		}
		putchar( '\n' );
	}
}
/**
 * 把缓冲区中的数据保存为灰度图像文件
 */
 #if 0
int store_image(unsigned char *buffer, const char *image_name)
{
	int i, j, ret = 0;
 
	// 创建新的位图对象
	FIBITMAP *bitmap = FreeImage_Allocate(g_width, g_height, 32);
	if (bitmap == NULL) {
		printf("alloc bitmap fail\n");
		return EXIT_FAILURE;
	}
 
	uint8_t *bits = FreeImage_GetBits(bitmap);
	for (i = 0; i < g_width * g_height; i++) {
		for (j = 0; j < 3; j++)
		{
			bits[i*4+j] = buffer[i];
		}
		bits[i*4+3]=255;
	}
	FreeImage_Save(g_format, bitmap, image_name);
	FreeImage_Unload(bitmap);
	return ret;
}
#endif
#ifdef USE_ICONV


int code_convert(char *from_charset,char *to_charset,const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
    iconv_t cd;
    int rc;
    char **pin = (char**)&inbuf;
    char **pout = &outbuf;
     
    cd = iconv_open(to_charset,from_charset);
    if(cd == (iconv_t)-1) {
    	perror("iconv_open");
    }
    if (cd==0) {
    	perror("cd is zero");
    	return -1;
    }
    memset(outbuf,0,outlen);
    if(iconv(cd,pin,&inlen,pout,&outlen)==-1){
    	perror("iconv");
    	 return -1;
    }
    iconv_close(cd);
    return 0;
}



int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
    return code_convert("utf-8","gbk",inbuf,inlen,outbuf,outlen);
}

int KM_GBK2UTF(const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	return code_convert("gb18030","utf-8",inbuf,inlen,outbuf,outlen);
}
int KM_UTF2GBK(const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	return code_convert("utf-8","gbk",inbuf,inlen,outbuf,outlen);
}
int KM_UTF2UNICODE(const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	return code_convert("utf-8","UCS-4LE",inbuf,inlen,outbuf,outlen);
	//return code_convert("utf-8","UCS-2BE",inbuf,inlen,outbuf,outlen);
}

#endif
//zh_CN.utf8
int ToWchar(char* src, wchar_t* dest, int len)
{
	int w_size = 0;
	char *p;
	if (src == NULL) {
		dest = NULL;
		return 0;
	}
	// 根据环境变量设置locale
	//p = setlocale(LC_CTYPE, "zh_CN.utf8");
	p = setlocale(LC_CTYPE, "");
	if(p == NULL) {
		//fprintf(stderr, "can't set the locale\n");
		perror("set fail");
		return -1;
	}
	printf("local:%s\n", p);
	// 得到转化为需要的宽字符大小
	w_size = mbstowcs(NULL, src, 0) + 1;
	// w_size = 0 说明mbstowcs返回值为-1。即在运行过程中遇到了非法字符(很有可能使locale
	// 没有设置正确)
	if (w_size == 0) {
		printf("not get utf8 here\n");
		dest = NULL;
		return -1;
	}
	if(len < w_size) {
		printf("dest size is not enough\n");
		return -1;
	}

	int ret = mbstowcs(dest, src, strlen(src)+1);
	if (ret <= 0) {
		return -1;
	}
	return w_size;
}

#define		WCHAR_SIZE	200

int main(int argc, char** argv)
{
	FT_Library    library;
	FT_Face       face;
	FT_GlyphSlot  slot;
	FT_Matrix     matrix;                 /* transformation matrix */
	FT_Vector     pen;                    /* untransformed origin  */
	FT_Error      error;

	char*         filename;
	char*         text;

	double        angle;
	int           target_height;
	int           n, num_chars;
	int ret;
	int i;
	//gcc example.c -o example -lfreetype -lm -finput-charset=GBK -fexec-charset=UTF-8
	//加入-finput-charset=GBK -fexec-charset=UTF-8
	// wide char string
	//wchar_t *chinese_str = L"你好";
	wchar_t *chinese_str;
	wchar_t buf_input[WCHAR_SIZE] = {0};
	unsigned char output[200] = {0};
	char *tmp_p;
	//char input[200] = {0xe4,0xbd,0xa0};
	char input[200] = {0};
	int in_len = 0;
	int out_len = 0;
	if ( argc != 3 )
	{
		fprintf ( stderr, "usage: %s font sample-text\n", argv[0] );
		exit( 1 );
	}


	filename      = argv[1];                           /* first argument     */
	text          = argv[2];                           /* second argument    */

	strcpy(input, argv[2]);
	//sprintf(input, "%s", "严");

	#ifndef USE_ICONV
	ret = ToWchar(input, buf_input, WCHAR_SIZE);
	if(ret <= 0) {
		printf("char to wchar fail\n");
		//return 0;	
	}
	#else

	in_len = strlen(input);
	out_len = sizeof(output);
	ret = KM_UTF2UNICODE(input, in_len, output, out_len);
	//ret = utf8_to_unicode(input, &in_len, output, &out_len);
	if(ret != 0) {
		printf("gbk to utf8 fail\n");	
		strcpy(output, input);
	} 
	
	//0x60,0x4f,0x0,0x0,0x7d,0x59,0x0,0x0
	//e4, bd, a0, e5, a5, bd
	#if 0
	for(i = 0; i < out_len; i++) {
		buf_input[i] = output[i*2] | output[i*2+1]<<8;	
		printf("input:0x%x, 0x%x, 0x%x, 0x%x\n", input[i], output[i], output[i*2+1], buf_input[i*2]);
	}	
	#else
	memcpy(buf_input, output, out_len);
	#endif
	
	
	#endif


	chinese_str = buf_input;
	//chinese_str = (wchar_t *)output;
	//num_chars     = strlen( text );
	num_chars = wcslen(chinese_str);
	
	printf("input<%s>, out<%s>\n", input, output);
	tmp_p = (char*)buf_input;
	printf("wchar is <");
	for(i = 0; i < num_chars*4; i++) {
		printf("0x%x", tmp_p[i]);
		if(i != (num_chars*4 - 1)) {
			printf(",");

		}
	}
	printf(">\n");
	
	printf("num_chars:%d\n", num_chars);
	angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 0 degrees  旋转     */
	target_height = HEIGHT;

	error = FT_Init_FreeType( &library );              /* initialize library */
	/* error handling omitted */

	error = FT_New_Face( library, filename, 0, &face );/* create face object */
	/* error handling omitted */

	/* use 30dot at 72dpi    */
	//字符的像素为: 30*64* (1/64) * (1/72)*72
	error = FT_Set_Char_Size( face, 30 * 64, 0,	72, 0 );                /* set character size */
	/* error handling omitted */
	//error = FT_Set_Pixel_Sizes( face, 0,24); 

	slot = face->glyph;

	/* set up matrix */
	matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
	matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
	matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
	matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );

	/* the pen position in 26.6 cartesian space coordinates; */
	/* start at (40,0) relative to the upper left corner  */
	pen.x = 0 * 64;
	//pen.y = ( target_height - 40 ) * 64;
	pen.y = 4*64;
	for ( n = 0; n < num_chars; n++ )
	{
		/* set transformation */
		FT_Set_Transform( face, &matrix, &pen );

		/* load glyph image into the slot (erase previous one) */
		//error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
		error = FT_Load_Char( face, chinese_str[n], FT_LOAD_RENDER );
		if ( error )
			continue;                 /* ignore errors */

		/* now, draw to our target surface (convert position) */
		draw_bitmap( &slot->bitmap,
				slot->bitmap_left,
				target_height - slot->bitmap_top );

		/* increment pen position */
		pen.x += slot->advance.x;
		pen.y += slot->advance.y;
	}
	show_image();

	FT_Done_Face    ( face );
	FT_Done_FreeType( library );

	return 0;
}

/* EOF */
gcc example.c -o example -lfreetype -lm
gcc example.c -o example -lfreetype -lm -finput-charset=GBK -fexec-charset=UTF-8
gcc example.c -o example -lfreetype -lm -liconv

arm-linux-gnueabi-gcc example.c -o example -lfreetype -lm -liconv  -I./ -L./arm -Wl,-rpath-link=./arm
需要准备好libfreetype.so,libiconv.so,libz.so.1

 

2.使用FreeImage图形库和freetype显示字符及保存图片

/* example1.c                                                      */
/*                                                                 */
/* This small program shows how to print a rotated string with the */
/* FreeType 2 library.                                             */


#include 
#include 
#include 
#include 
#include 
#include 
#include FT_FREETYPE_H
#include "FreeImage.h"




#define		USE_ICONV
#ifdef USE_ICONV
#include "iconv.h"
#endif



#define WIDTH   120
#define HEIGHT  30


//#define WIDTH   400
//#define HEIGHT  300

/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];


/* Replace this function with something useful. */

void draw_bitmap(FT_Bitmap*  bitmap, FT_Int x, FT_Int y)
{
	FT_Int  i, j, p, q;
	FT_Int  x_max = x + bitmap->width;
	FT_Int  y_max = y + bitmap->rows;

	for ( i = x, p = 0; i < x_max; i++, p++ )
	{
		#if 0
		//reverse height
		//for ( j = y, q = 0; j < y_max; j++, q++ )
		#else
		for ( j = y_max - 1, q = 0; j >= y; j--, q++ )
		#endif
		{
			if ( i < 0 || j < 0 || i >= WIDTH || j >= HEIGHT ) {
				continue;
			}
			image[j][i] |= bitmap->buffer[q * bitmap->width + p];
		}
	}
}

void show_image(void)
{
	int  i, j;

	for ( i = 0; i < HEIGHT; i++ )
	{
		for ( j = 0; j < WIDTH; j++ ) {
			putchar(image[i][j] == 0 ? ' ' : image[i][j] < 128 ? '+' : '*');
		}
		putchar( '\n' );
	}
}

long get_cur_ms(void) 
{
	long t = 0;
	struct timeval time;

	gettimeofday(&time, NULL);
	t = ((long)time.tv_sec)*1000 + (long)time.tv_usec/1000;
	return t;
}


/**
 * 把缓冲区中的数据保存为灰度图像文件
 */
int g_width = 0;
int g_height = 0;
FREE_IMAGE_FORMAT g_format = FIF_PNG;
int store_image(unsigned char *buffer, const char *image_name)
{
	int i, j, ret = 0;
 
 	g_width = WIDTH;
 	g_height = HEIGHT;
	// 创建新的位图对象
	FIBITMAP *bitmap = FreeImage_Allocate(g_width, g_height, 32, 8, 8, 8);
	if (bitmap == NULL) {
		printf("alloc bitmap fail\n");
		return EXIT_FAILURE;
	}
 
	unsigned char *bits = FreeImage_GetBits(bitmap);
	for (i = 0; i < g_width * g_height; i++) {
		for (j = 0; j < 3; j++)
		{
			bits[i*4+j] = buffer[i];
		}
		bits[i*4+3]=255;
	}
	FreeImage_Save(g_format, bitmap, image_name, PNG_DEFAULT);
	//FreeImage_Save(g_format, bitmap, image_name, PNG_DEFAULT);
	FreeImage_Unload(bitmap);
	return ret;
}

#ifdef USE_ICONV


int code_convert(char *from_charset,char *to_charset,const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
    iconv_t cd;
    int rc;
    char **pin = (char**)&inbuf;
    char **pout = &outbuf;
     
    cd = iconv_open(to_charset,from_charset);
    if(cd == (iconv_t)-1) {
    	perror("iconv_open");
    }
    if (cd==0) {
    	perror("cd is zero");
    	return -1;
    }
    memset(outbuf,0,outlen);
    if(iconv(cd,pin,&inlen,pout,&outlen)==-1){
    	perror("iconv");
    	 return -1;
    }
    iconv_close(cd);
    return 0;
}



int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
    return code_convert("utf-8","gbk",inbuf,inlen,outbuf,outlen);
}

int KM_GBK2UTF(const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	return code_convert("gb18030","utf-8",inbuf,inlen,outbuf,outlen);
}
int KM_UTF2GBK(const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	return code_convert("utf-8","gbk",inbuf,inlen,outbuf,outlen);
}
int KM_UTF2UNICODE(const char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	return code_convert("utf-8","UCS-4LE",inbuf,inlen,outbuf,outlen);
	//return code_convert("utf-8","UCS-2BE",inbuf,inlen,outbuf,outlen);
}

#endif
//zh_CN.utf8
int ToWchar(char* src, wchar_t* dest, int len)
{
	int w_size = 0;
	char *p;
	if (src == NULL) {
		dest = NULL;
		return 0;
	}
	// 根据环境变量设置locale
	//p = setlocale(LC_CTYPE, "zh_CN.utf8");
	p = setlocale(LC_CTYPE, "");
	if(p == NULL) {
		//fprintf(stderr, "can't set the locale\n");
		perror("set fail");
		return -1;
	}
	printf("local:%s\n", p);
	// 得到转化为需要的宽字符大小
	w_size = mbstowcs(NULL, src, 0) + 1;
	// w_size = 0 说明mbstowcs返回值为-1。即在运行过程中遇到了非法字符(很有可能使locale
	// 没有设置正确)
	if (w_size == 0) {
		printf("not get utf8 here\n");
		dest = NULL;
		return -1;
	}
	if(len < w_size) {
		printf("dest size is not enough\n");
		return -1;
	}

	int ret = mbstowcs(dest, src, strlen(src)+1);
	if (ret <= 0) {
		return -1;
	}
	return w_size;
}

#define		WCHAR_SIZE	200

int main(int argc, char** argv)
{
	FT_Library    library;
	FT_Face       face;
	FT_GlyphSlot  slot;
	FT_Matrix     matrix;                 /* transformation matrix */
	FT_Vector     pen;                    /* untransformed origin  */
	FT_Error      error;

	char*         filename;
	char*         text;

	double        angle;
	int           target_height;
	int           n, num_chars;
	int ret;
	int i;
	long t;
	//gcc example.c -o example -lfreetype -lm -finput-charset=GBK -fexec-charset=UTF-8
	//加入-finput-charset=GBK -fexec-charset=UTF-8
	// wide char string
	//wchar_t *chinese_str = L"你好";
	wchar_t *chinese_str;
	wchar_t buf_input[WCHAR_SIZE] = {0};
	unsigned char output[200] = {0};
	char *tmp_p;
	//char input[200] = {0xe4,0xbd,0xa0};
	char input[200] = {0};
	int in_len = 0;
	int out_len = 0;
	if ( argc != 3 )
	{
		fprintf ( stderr, "usage: %s font sample-text\n", argv[0] );
		exit( 1 );
	}


	filename      = argv[1];                           /* first argument     */
	text          = argv[2];                           /* second argument    */

	strcpy(input, argv[2]);
	//sprintf(input, "%s", "严");

	#ifndef USE_ICONV
	ret = ToWchar(input, buf_input, WCHAR_SIZE);
	if(ret <= 0) {
		printf("char to wchar fail\n");
		//return 0;	
	}
	#else

	in_len = strlen(input);
	out_len = sizeof(output);
	t = get_cur_ms();
	ret = KM_UTF2UNICODE(input, in_len, output, out_len);
	//ret = utf8_to_unicode(input, &in_len, output, &out_len);
	if(ret != 0) {
		printf("gbk to utf8 fail\n");	
		strcpy(output, input);
	} 
	
	//0x60,0x4f,0x0,0x0,0x7d,0x59,0x0,0x0
	//e4, bd, a0, e5, a5, bd
	#if 0
	for(i = 0; i < out_len; i++) {
		buf_input[i] = output[i*2] | output[i*2+1]<<8;	
		printf("input:0x%x, 0x%x, 0x%x, 0x%x\n", input[i], output[i], output[i*2+1], buf_input[i*2]);
	}	
	#else
	memcpy(buf_input, output, out_len);
	#endif
	
	
	#endif


	chinese_str = buf_input;
	//chinese_str = (wchar_t *)output;
	//num_chars     = strlen( text );
	num_chars = wcslen(chinese_str);
	
	printf("input<%s>, out<%s>\n", input, output);
	tmp_p = (char*)buf_input;
	printf("wchar is <");
	for(i = 0; i < num_chars*4; i++) {
		printf("0x%x", tmp_p[i]);
		if(i != (num_chars*4 - 1)) {
			printf(",");

		}
	}
	printf(">\n");
	
	printf("num_chars:%d\n", num_chars);
	printf("to wchar cost %dms\n", get_cur_ms() - t);
	t = get_cur_ms();
	angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 0 degrees  旋转     */
	target_height = HEIGHT;

	error = FT_Init_FreeType( &library );              /* initialize library */
	/* error handling omitted */

	error = FT_New_Face( library, filename, 0, &face );/* create face object */
	/* error handling omitted */

	/* use 30dot at 72dpi    */
	//字符的像素为: 30*64* (1/64) * (1/72)*72
	error = FT_Set_Char_Size( face, 30 * 64, 0,	72, 0 );                /* set character size */
	/* error handling omitted */
	//error = FT_Set_Pixel_Sizes( face, 0,24); 

	slot = face->glyph;

	/* set up matrix */
	matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
	matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
	matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
	matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );

	/* the pen position in 26.6 cartesian space coordinates; */
	/* start at (40,0) relative to the upper left corner  */
	pen.x = 0 * 64;
	//pen.y = ( target_height - 40 ) * 64;
	pen.y = 4*64;
	//pen.y = 40*64;
	for ( n = 0; n < num_chars; n++ )
	{
		/* set transformation */
		FT_Set_Transform( face, &matrix, &pen );

		/* load glyph image into the slot (erase previous one) */
		//error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
		error = FT_Load_Char( face, chinese_str[n], FT_LOAD_RENDER );
		if ( error )
			continue;                 /* ignore errors */

		/* now, draw to our target surface (convert position) */
		draw_bitmap( &slot->bitmap,
				slot->bitmap_left,
				target_height - slot->bitmap_top );

		/* increment pen position */
		pen.x += slot->advance.x;
		pen.y += slot->advance.y;
	}
	printf("translate cost %dms\n", get_cur_ms() - t);
	t = get_cur_ms();
	show_image();

	FT_Done_Face    ( face );
	FT_Done_FreeType( library );
	printf("show_image cost %dms\n", get_cur_ms() - t);
	t = get_cur_ms();
	store_image((unsigned char*)image, "./tmp.png");
	printf("store_image cost %dms\n", get_cur_ms() - t);
	
	return 0;
}

/* EOF */

 

gcc example.c -o example -lfreetype -lm -liconv -lfreeimage

libfreeimge

安装

https://blog.csdn.net/jacke121/article/details/60139468?utm_source=blogxgwz5

你可能感兴趣的:(freetype使用文泉驿显示及保存图片)