大家好,我上个周末都在尝试在屏幕上放置png图像,但没有成功。我左右寻找原因,但无论如何尝试,我似乎都找不到为什么有人可以将我指向正确的方向?

我使用this作为模板。
然后我看着所有这些:

libX11: XPutImage first call

Having issues with XPutImage

displaying png file using XPutImage does not work

但什么也没偷

XPutImage(display,
              *window,
              ((mc_drawable *)this)->_gc,
              this->image,
              0, 0,
              0, 0,
              this->_y, this->_x);


这就是我使用XPutImage的方式

#include <png.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include "modular/raise.h"
#include "internal/drawable/imagepr.h"
#include "internal/server_connection.h"

static void chechFile(
    FILE *file)
{
    unsigned char nbr[8] = "";

    fread(nbr, 1, 8, file);
    if (png_sig_cmp(nbr, 0, 8) != 0) {
        raise("not a Png file");
    }
}

static char parsePng(
    FILE *file,
    mc_imagePr *image)
{
    char *data = NULL;
    png_struct *pngPtr = png_create_read_struct(
        PNG_LIBPNG_VER_STRING,
        NULL, NULL, NULL);
    png_info *pngInfo = NULL;
    int readFlag = PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND;
    int colorType = 0;
    int interlaceMethod = 0;
    int rowBytes = 0;
    png_uint_32 index = 0;
    png_bytepp rowPointers = NULL;
    png_uint_32 width = 0;
    png_uint_32 height = 0;
    int bitDepth = 0;
    Display *dys = getDisplay();

    if (!pngPtr) {
        return (0);
    } else if (!(pngInfo = png_create_info_struct(pngPtr))) {
        png_destroy_read_struct(&pngPtr, NULL, NULL);
        return (0);
    }
    if (setjmp(png_jmpbuf(pngPtr))) {
        png_destroy_read_struct(&pngPtr, &pngInfo, NULL);
        return (0);
    }
    png_init_io(pngPtr, file);
    png_set_sig_bytes(pngPtr, 8);
    png_read_png(pngPtr, pngInfo, readFlag, NULL);
    png_get_IHDR(pngPtr,
                 pngInfo,
                 &width, &height,
                 &bitDepth,
                 &colorType,
                 &interlaceMethod,
                 NULL,
                 NULL);

    rowBytes = png_get_rowbytes(pngPtr, pngInfo);
    data = malloc(rowBytes * height);
    if (!data) {
        png_destroy_read_struct(&pngPtr, &pngInfo, NULL);
        return (0);
    }
    rowPointers = png_get_rows(pngPtr, pngInfo);
    while (index < height) {
        memcpy(data + (index * rowBytes),
               rowPointers[index],
               rowBytes);
        ++index;
    }
    printf("PNG %d * %d\n rowbytes %d\n depth %d\ncolor type %d\n",
           width,
           height,
           rowBytes,
           bitDepth,
           colorType);
    image->image = XCreateImage(
        dys,
        CopyFromParent,
        DefaultDepth(
            dys,
            DefaultScreen(dys)),
        ZPixmap,
        0,
        data,
        width,
        height,
        32,
        rowBytes);
    png_destroy_info_struct(pngPtr, &pngInfo);
    png_destroy_read_struct(&pngPtr, &pngInfo, NULL);
    return (1);
}

char readPng(
    const char *path,
    mc_imagePr *image)
{
    FILE *fd = fopen(path, "r");
    char res = 0;

    if (!fd) {
        raise("file not found\n");
    }
    chechFile(fd);
    res = parsePng(
        fd,
        image);
    fclose(fd);
    return (res);
}


这是我用来创建XImage的文件

编辑:

阅读N.M.的回复后,我尝试绘制50 x 50的白色图像
再次成功。惠特奇(Whitch)的意思是,我真的不理解XPutImage的工作原理。这是我的测试:

 #include <memory.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <X11/Xlib.h>
 #include <stdio.h>
 #include <unistd.h>

 int main(void)
 {
     Window window;
     Display *display = XOpenDisplay();
     XSetWindowAttributes test = {};
     XEvent e;
     GC gc;
     int whiteColor;
     Atom delWin = XInternAtom(display, "WM_DELETE_WINDOW", True);
     XImage *image = NULL;
     char *data = malloc(50 * 50 * 4);

     memset(data, 250, 50 * 50 * 4);
     if (!display) {
         return (84);
     }
     window = XCreateWindow(
         display,
         XDefaultRootWindow(display),
         0, 0,
         500, 500,
         100,
         CopyFromParent,
         CopyFromParent,
         CopyFromParent,
         0,
         &test);
     XSelectInput(display, window, StructureNotifyMask);
     XMapWindow(display, window);
     gc = XCreateGC(display, window, 0, 0);
     whiteColor = WhitePixel(display, DefaultScreen(display));
     XSetForeground(display, gc, whiteColor);
     XSetWMProtocols(display, window, &delWin, 1);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == MapNotify)
             break;
     }
     XFlush(display);
         image = XCreateImage(
         display,
         CopyFromParent,
         DefaultDepth(
             display,
             DefaultScreen(display)),
         ZPixmap,
         0,
         data,
         50,
         50,
         32,
         50 * 4);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == DestroyNotify ||
             (e.type == ClientMessage &&
              e.xclient.data.l[0] == (long)delWin))
             break;
         XPutImage(
             display,
             window,
             gc,
             image,
             0, 0,
             50, 50,
             0, 0);
     }
     XCloseDisplay(display);
     return (0);

最佳答案

我觉得有点傻,但是我只交换了两行,却看不到它。感谢n.m.我如何解决这个问题

int main(void)
{
     Window window;
     Display *display = XOpenDisplay();
     XSetWindowAttributes test = {};
     XEvent e;
     GC gc;
     int whiteColor;
     Atom delWin = XInternAtom(display, "WM_DELETE_WINDOW", True);
     XImage *image = NULL;
     char *data = malloc(50 * 50 * 4);

     memset(data, 250, 50 * 50 * 4);
     if (!display) {
         return (84);
     }
     window = XCreateWindow(
         display,
         XDefaultRootWindow(display),
         0, 0,
         500, 500,
         100,
         CopyFromParent,
         CopyFromParent,
         CopyFromParent,
         0,
         &test);
     XSelectInput(display, window, StructureNotifyMask);
     XMapWindow(display, window);
     gc = XCreateGC(display, window, 0, 0);
     whiteColor = WhitePixel(display, DefaultScreen(display));
     XSetForeground(display, gc, whiteColor);
     XSetWMProtocols(display, window, &delWin, 1);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == MapNotify)
             break;
     }
     XFlush(display);
         image = XCreateImage(
         display,
         CopyFromParent,
         DefaultDepth(
             display,
             DefaultScreen(display)),
         ZPixmap,
         0,
         data,
         50,
         50,
         32,
         50 * 4);
     while (1) {
         XNextEvent(display, &e);
         if (e.type == DestroyNotify ||
             (e.type == ClientMessage &&
              e.xclient.data.l[0] == (long)delWin))
             break;
         XPutImage(
             display,
             window,
             gc,
             image,
             0, 0,  // from which offset to start drawing
             0, 0,  // position on the screen
             50, 50); // width and height of what you want to draw
     }
     XCloseDisplay(display);
     return (0);

09-27 00:33