gpt4 book ai didi

c - 使用 Cairo 和 C 旋转和合成 PNG 文件

转载 作者:行者123 更新时间:2023-11-30 15:56:29 24 4
gpt4 key购买 nike

我正在使用 C 中的 Cairo 编写一个应用程序,该应用程序执行以下操作:

  • 加载背景 PNG(轮子)
  • 将轮子旋转 90 度
  • 在轮子上绘制来自其他 PNG 文件的一组数字
  • 这样做,直到轮盘的所有 6 个部分都绘制了轮盘上的数字
  • 将 PNG 保存到文件 ( results.png )

我遇到的问题是,如果我不旋转轮子,数字就会正确绘制,如image所示。 ,除非轮子没有根据需要旋转。

但是,如果我尝试旋转并在轮子上绘制数字,我会得到一个没有数字的旋转轮子,如 image. 中所示。

我尝试了代码的各种排列,但似乎无法使其工作。我希望得到一些提示和/或示例代码来显示我做错了什么。我检查了 Cairo 文档,但没有结果。

代码可以找到here.

这里:

#include <cairo.h>
#include <stdio.h>
#include <string.h>
#include <math.h>


typedef struct
{
int numImages; /* Number of images in win amount string */
int indexes[7]; /* indexes into NumberImages[] */
}WinAmountData;

/***** Function Prototypes *****************/
int InitImages( void );
void DestroyNumberImages( void );
int ParseWinAmountString( char *string, WinAmountData *amtData );
int Rotate( cairo_t *cr , cairo_surface_t *image, double degrees );
/*******************************************/


typedef struct
{
int xOffset; /* pixel count offsete before next digit */
char fileName[20];
cairo_surface_t *image;
}ImageInfo;

ImageInfo NumberImages[] =
{
{ 8, "images/0.png", NULL },
{ 10, "images/1.png", NULL },
{ 10, "images/2.png", NULL },
{ 10, "images/3.png", NULL },
{ 10, "images/4.png", NULL },
{ 10, "images/5.png", NULL },
{ 10, "images/6.png", NULL },
{ 10, "images/7.png", NULL },
{ 10, "images/8.png", NULL },
{ 10, "images/9.png", NULL },
{ 7, "images/$.png", NULL },
{ 10, "images/euro.png", NULL },
{ 7, "images/pound.png", NULL },
{ 7, "images/yen.png", NULL }
};

enum { DOLLAR = 10, EURO, POUND, YEN };

#define FALSE 0
#define TRUE 1

int InitImages( void )
{
int i;
int ret = TRUE;
cairo_status_t imgStatus;


for( i = 0; i < ( sizeof( NumberImages ) / sizeof( ImageInfo ) ) && ret == TRUE; i++ )
{
NumberImages[i].image = cairo_image_surface_create_from_png( NumberImages[i].fileName );
imgStatus = cairo_surface_status(NumberImages[i].image);
ret = ( CAIRO_STATUS_SUCCESS == imgStatus );
}

return( ret );
}


void DestroyNumberImages( void )
{
int i;

for( i = 0; i < ( sizeof( NumberImages ) / sizeof( ImageInfo ) ); i++ )
{
cairo_surface_destroy(NumberImages[i].image);
}

return;
}

int ParseWinAmountString( char *string, WinAmountData *amtData )
{
int ret = TRUE;
int i = 0, len;

len = strlen( string );
if( (len > 0) && (len < 8) )
{
amtData->numImages = len;

for( i = 0; i < amtData->numImages && TRUE == ret; i++ )
{
if( string[i] >= '0' && string[i] <= '9' )
{
amtData->indexes[i] = string[i] - '0';
}
else
{
switch( string[i] )
{
case 'D':
amtData->indexes[i] = DOLLAR;
break;

case 'Y':
amtData->indexes[i] = YEN;
break;

case 'E':
amtData->indexes[i] = EURO;
break;

case 'P':
amtData->indexes[i] = POUND;
break;

default:
ret = FALSE;
break;
}
}
}
}
else
{
ret = FALSE;
}

return( ret );
}

double DegreesToRadians( double degrees )
{
return((double)((double)degrees * ( (double)M_PI/(double)180.0 )));
}

int Rotate( cairo_t *cr , cairo_surface_t *image, double degrees )
{
int ret = 0;

cairo_translate(cr, 90, 90);
cairo_rotate(cr, DegreesToRadians( degrees ));
cairo_set_source_surface(cr, image, -90, -90);

cairo_paint(cr);

return ( ret );
}


int main(int argc, char *argv[])
{
int i,x,y;
cairo_surface_t *imgWheelBg = NULL;
WinAmountData amtData;


if( argc == 2 )
{
printf("Parsing [%s]\n", argv[1]);
if ( ParseWinAmountString( argv[1], &amtData ) == TRUE )
{
printf("Amount indexes = [ ");
for( i = 0; i < amtData.numImages; i++ )
{
printf("%d ", amtData.indexes[i]);
}
printf("]\n");
}
else
{
printf("Failed to parse amount.\n");
return( 1 );
}
}
else
{
printf("Usage: %s <Amount String>\n", argv[0]);
return( 1 );
}

if( InitImages() == TRUE )
{
imgWheelBg = cairo_image_surface_create_from_png("images/blankwheel.png");

//Create the background image
cairo_surface_t *imgResult = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 180, 180);

//Create the cairo context
cairo_t *cr = cairo_create(imgResult);

//Paint empty wheel image
cairo_set_source_surface(cr, imgWheelBg, 0, 0);
cairo_paint(cr);

// At this point the wheel is painted ( blankwheel.png )

// vvvvvvvvvv THIS PART SEEMS TO BE CAUSING TROUBLES vvvvvvvvvv

// With this call the wheel DOES get rotated 90 degress. Confirmed
// by viewing the resulting PNG file.
// HOWEVER, after the Rotate() is called the numbers aren't put on the wheel.
// if I remove the Rotate() call, the wheel is drawn, not rotated, but the
// numbers are properly composited over the image.

//Rotate( cr, imgWheelBg, 90 );

// ^^^^^^^^^^^ THIS PART SEEMS TO BE CAUSING TROUBLES ^^^^^^^^^^^

/* Set drawing begin point in pixels */
x = 101;
y = 82;

/* Draw all characters in win amount string */
for( i = 0; i < amtData.numImages; i++ )
{
cairo_set_source_surface(cr, NumberImages[amtData.indexes[i]].image, x, y);
cairo_paint(cr);
x += NumberImages[i].xOffset;
}

//Destroy the cairo context and/or flush the destination image
cairo_surface_flush(imgResult);
cairo_destroy(cr);

//And write the results into a new file
cairo_surface_write_to_png(imgResult, "result.png");

// Destroy resources
cairo_surface_destroy(imgResult);
cairo_surface_destroy(imgWheelBg);
DestroyNumberImages();
printf("SUCCESS\n");
}
else
{
printf("FAILED Init Images\n");
}

return 0;
}

编辑:最终目标是生成图像 like this one以编程方式在 GTK 应用程序中根据需要实时制作动画。

编辑:来自 Mikhail Kozhevnikov 的评论和 Uli Schlachter我能够使用 this code 找到解决方案.

非常感谢!

最佳答案

我认为问题在于,变换应用于所有内容,包括数字图像,并且由于这种变换,它们被绘制在图片之外的某个地方。我建议the matrix be stored在应用转换之前和 restored画完圆之后。或者您希望数字也旋转吗?..

关于c - 使用 Cairo 和 C 旋转和合成 PNG 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11249801/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com