bitmap - 使用 XLib,如何将 Windows 位图文件读入 Pixmap
问题描述
使用 XLib,将位图(Windows 格式)读入 Pixmap 对象。
解决方案
这是我想出的:它返回 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;
}
推荐阅读
- node.js - how to send a custom notification to my google home mini using the cloud function?
- c++ - 现有文件中的 pdfium 链接(使用 ubuntu)
- javascript - 使用 react-native-firebase-mlkit 时相机未检测到纵向模式下的文本?
- php - Laravel 5.6:页面由于不活动而过期
- java - 如何以编程方式设置 MultiSelectListPreference 的复选框值?
- git - 无法将提交推送到我的 git 存储库
- elasticsearch - 如何使用groovy脚本在elasticsearch中获取具有给定ID的特定文档是否存在
- azure - azure ad 中的 windows 应用程序需要注册
- android - 基于使用的主题的 BottomNavigationView 文本调整大小动画问题
- dynamics-crm - 功能区工作台在发布后自动添加两个命令