gpt4 book ai didi

x11 - 使用 XPutImage 显示 png 文件不起作用

转载 作者:行者123 更新时间:2023-12-04 16:27:59 27 4
gpt4 key购买 nike

我尝试使用 xputimage 在 xwindow 中显示一个 png 文件。但是 xputimage 抛出以下错误:

window width - '426'; height - '341'

X Error of failed request: BadMatch (invalid parameter attributes) Major opcode of failed request: 72 (X_PutImage) Serial number of failed request: 11 Current serial number in output stream: 12

我尝试更改 xputimage 的参数,但仍然出现相同的错误。请帮帮我..

源码如下:

/*
* simple-drawing.c - demonstrate drawing of pixels, lines, arcs, etc.
* on a window. All drawings are done in black color
* over a white background.
*/

#include <X11/Xlib.h>`

#include <stdio.h>`

#include <stdlib.h> /* getenv(), etc. */`

#include <unistd.h> /* sleep(), etc. */`

#include <png.h>`



Window
create_simple_window(Display* display, int width, int height, int x, int y)

{

int screen_num = DefaultScreen(display);

int win_border_width = 2;

Window win;


win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
x, y, width, height, win_border_width,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));

/* make the window actually appear on the screen. */

XMapWindow(display, win);

/* flush all pending requests to the X server. */

XFlush(display);

return win;

}

GC create_gc(Display* display, Window win, int reverse_video)

{

GC gc; /* handle of newly created GC. */

unsigned long valuemask = 0; /* which values in 'values' to */

/* check when creating the GC. */

XGCValues values; /* initial values for the GC. */

unsigned int line_width = 2; /* line width for the GC. */

int line_style = LineSolid; /* style for lines drawing and */

int cap_style = CapButt; /* style of the line's edje and */

int join_style = JoinBevel; /* joined lines. */

int screen_num = DefaultScreen(display);

gc = XCreateGC(display, win, valuemask, &values);

if (gc < 0) {

fprintf(stderr, "XCreateGC: \n");

}

/* allocate foreground and background colors for this GC. */

if (reverse_video) {

XSetForeground(display, gc, WhitePixel(display, screen_num));

XSetBackground(display, gc, BlackPixel(display, screen_num));

}

else {

XSetForeground(display, gc, BlackPixel(display, screen_num));

XSetBackground(display, gc, WhitePixel(display, screen_num));

}


XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);


XSetFillStyle(display, gc, FillSolid);

return gc;

}

static void TeardownPng (png_structp png, png_infop info)
{

if (png) {

png_infop *realInfo = (info? &info: NULL);

png_destroy_read_struct (&png, realInfo, NULL);

}

}

void LoadPng (FILE *file, unsigned char** data, char **clipData, unsigned int *width, unsigned int *height, unsigned int *rowbytes)

{

size_t size = 0, clipSize = 0;

png_structp png = NULL;

png_infop info = NULL;

unsigned char **rowPointers = NULL;

int depth = 0,
colortype = 0,
interlace = 0,
compression = 0,
filter = 0;

unsigned clipRowbytes = 0;


png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

info = png_create_info_struct (png);

png_init_io (png, file);

png_read_info (png, info);

png_get_IHDR (png, info, (png_uint_32*)width, (png_uint_32*)height, &depth, &colortype, &interlace, &compression, &filter);



*rowbytes = png_get_rowbytes (png, info);

if (colortype == PNG_COLOR_TYPE_RGB) {

// X hates 24bit images - pad to RGBA
png_set_filler (png, 0xff, PNG_FILLER_AFTER);

*rowbytes = (*rowbytes * 4) / 3;

}

png_set_bgr (png);


*width = png_get_image_width (png, info);

*height = png_get_image_height (png, info);

size = *height * *rowbytes;

clipRowbytes = *rowbytes/32;

if (*rowbytes % 32)

++clipRowbytes;

clipSize = clipRowbytes * *height;

// This gets freed by XDestroyImage

*data = (unsigned char*) malloc (sizeof (png_byte) * size);

rowPointers = (unsigned char**) malloc (*height * sizeof (unsigned char*));

png_bytep cursor = *data;

int i=0,x=0,y=0;

for (i=0; i<*height; ++i, cursor += *rowbytes)

rowPointers[i] = cursor;

png_read_image (png, rowPointers);

*clipData = (char*) calloc (clipSize, sizeof(unsigned char));

if (colortype == PNG_COLOR_TYPE_RGB) {

memset (*clipData, 0xff, clipSize);

} else {

// Set up bitmask for clipping fully transparent areas

for (y=0; y<*height; ++y, cursor+=*rowbytes) {

for (x=0; x<*rowbytes; x+=4) {

// Set bit in mask when alpha channel is nonzero

if(rowPointers[y][x+3])

(*clipData)[(y*clipRowbytes) + (x/32)] |= (1 << ((x/4)%8));

}

}

}

TeardownPng (png, info);

free (rowPointers);

}

void
main(int argc, char* argv[])

{

Display* display; /* pointer to X Display structure. */

int screen_num; /* number of screen to place the window on. */

Window win; /* pointer to the newly created window. */

unsigned int display_width,
display_height; /* height and width of the X display. */

unsigned int width, height; /* height and width for the new window. */

char *display_name = getenv("DISPLAY"); /* address of the X display. */

GC gc; /* GC (graphics context) used for drawing */

/* in our window. */

unsigned width_ = 0, height_ = 0;


unsigned char *data = NULL;

char *clip = NULL;

unsigned rowbytes = 0;

unsigned long *image, *mask;

/* open connection with the X server. */

display = XOpenDisplay(display_name);

if (display == NULL) {

fprintf(stderr, "%s: cannot connect to X server '%s'\n",
argv[0], display_name);

exit(1);

}

/* get the geometry of the default screen for our display. */
screen_num = DefaultScreen(display);

display_width = DisplayWidth(display, screen_num);

display_height = DisplayHeight(display, screen_num);

/* make the new window occupy 1/9 of the screen's size. */

width = (display_width / 3);

height = (display_height / 3);

printf("window width - '%d'; height - '%d'\n", width, height);



win = create_simple_window(display, width, height, 0, 0);


gc = create_gc(display, win, 0);

XSync(display, False);

/* catch expose events */

XSelectInput(display, win, ExposureMask);

/* wait for the expose event */

XEvent ev;

XNextEvent(display, &ev);

// Load image

FILE *file = fopen ("/games/splash_image.png", "r");

if (!file)

return;

LoadPng (file, &data, &clip, &width_, &height_, &rowbytes);

if (!data)

return;
XImage *ximage = XCreateImage (display, DefaultVisual (display, DefaultScreen (display)), 32, ZPixmap, 0, (char*)data, width, height, 8, rowbytes);

if (ximage) {

XPutImage (display, win, gc, ximage, 0, 0, 0, 0, width, height);

XNextEvent(display, &ev);

} else {

free (data);

}

// free (clip);

// Load Image end


/* flush all pending requests to the X server. */

XFlush(display);

XSync(display, False);

/* make a delay for a short period. */

sleep(4);

/* close the connection to the X server. */

XCloseDisplay(display);

}

最佳答案

如果参数不一致,XPutImage 将返回“BadMatch”。您正在指定 32 位的深度,但该深度可能不可用。在调用 XCreateImage 之前尝试检查默认深度。

printf("default depth = %d\n", DefaultDepth(display, screen_num));

更改传递给 XCreateImage 的“深度”参数以匹配 DefaultDepth 返回的值。

关于x11 - 使用 XPutImage 显示 png 文件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17857575/

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