首页 > 解决方案 > 使用 XLib,如何将 Windows 位图文件读入 Pixmap

问题描述

使用 XLib,将位图(Windows 格式)读入 Pixmap 对象。

标签: bitmapxlib

解决方案


这是我想出的:它返回 2 个像素图,一个用于图像,另一个(可选)用于遮罩。

// returns 2 pixmaps: Image + Mask
bool LoadBMP (Window window, char *Filename, Pixmap *image, Pixmap *mask)
  {
    bool res;
    int file;
    longint size;
    byte *buf;
    int offset;
    int sizeX, sizeY;
    int bpp, bytepp, bytepl, bytepad;
    int comp;
    GC pixmapgc, maskgc;
    int x, y;
    int col, coltrans;
    byte *ptr;
    //
    res = false;
    file = FileOpen (Filename, foRead);
    if (file > 0)
      {
        size = FileSize (file);
        if (size > 0)
          {
            buf = malloc (size);
            if (buf)
              {
                if (FileRead (file, buf, size) == size)
                  {
                    offset = *(int *) (buf + 0x0A);
                    sizeX = *(int *) (buf + 0x12);
                    sizeY = *(int *) (buf + 0x16);
                    bpp = *(int *) (buf + 0x1C);   // bits / pixel
                    comp = *(int *) (buf + 0x1E);
                    bytepp = bpp >> 3;
                    bytepl = (bytepp * sizeX + 3) & ~3;   // pixel lines are padded out to 4*n
                    bytepad = bytepl - bytepp * sizeX;
                    if (sizeX && sizeY && bytepp && offset < size && comp == 0)
                      {
                        *image = XCreatePixmap (XDisplay, window, sizeX, sizeY, XDepth);
                        *mask = XCreatePixmap (XDisplay, window, sizeX, sizeY, XDepth);
                        pixmapgc = XCreateGC (XDisplay, *image, 0, NULL);
                        maskgc = XCreateGC (XDisplay, *mask, 0, NULL);
                        XSetForeground (XDisplay, maskgc, 0x000000);
                        XFillRectangle (XDisplay, *mask, maskgc, 0, 0, sizeX, sizeY);
                        XSetForeground (XDisplay, maskgc, 0xFFFFFF);
                        x = 0;
                        y = sizeY - 1;
                        ptr = &buf [offset];
                        coltrans = -1;
                        while (y >= 0)
                          {
                            if (bytepp == 3)
                              col = *ptr++ | *ptr++ << 8 | *ptr++ << 16;
                            else if (bytepp == 2)
                              col = *ptr++ | *ptr++ << 8;
                            else
                              col = *ptr++;
                            if (coltrans < 0)
                              coltrans = col;
                            XSetForeground (XDisplay, pixmapgc, col);
                            XDrawPoint (XDisplay, *image, pixmapgc, x, y);
                            if (col != coltrans)
                              XDrawPoint (XDisplay, *mask, maskgc, x, y);
                            x++;
                            if (x >= sizeX)
                              {
                                x = 0;
                                y--;
                                ptr += bytepad;
                              }
                          }
                        res = true;
                      }
                  }
                free (buf);
              }
          }
        FileClose (file);
      }
    return res;
  }


推荐阅读