主程式 main.cpp:
#include <opencv2/opencv.hpp> // should include first to prevent conflic
#include <opencv2/highgui.hpp>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/cursorfont.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef unsigned char u8int;
typedef const char* c_str;
Display *display;
Window child;
GC gCtx;
XColor fgColor, black, white ,red, green, blue;
XImage *bg = nullptr;
int width = 0;
int height = 0;
void drawRect(int x, int y, int w, int h){
XDrawRectangle(display, child, gCtx, x, y, w, h);
}
void drawLine(int x1, int y1, int x2, int y2){
XDrawLine(display, child, gCtx, x1, y1, x2, y2);
}
void drawArc(int x, int y, int w, int h, int ang1, int ang2){
XDrawArc(display, child, gCtx, x, y, w, h, ang1 << 6, ang2 << 6);
}
void setColorMap(XColor &c, const char *str){
auto colormap = DefaultColormap(display, 0);
XParseColor(display, colormap, str, &c);
XAllocColor(display, colormap, &c);
}
void fgSetColor(XColor &c) {
fgColor = c;
XSetForeground(display, gCtx, c.pixel);
}
void setBackGround(u8int *src=nullptr, int sw=0, int sh=0, int sch=0){
if (bg) XDestroyImage(bg);
XWindowAttributes info;
XGetWindowAttributes(display, child, &info);
Visual *v = info.visual;
width = info.width ;
height = info.height;
int depth = info.depth;
int sline = sch * sw;
int dline= 4 * width;
int size = dline * height;
u8int *fb = (u8int *)malloc(size);
if(! fb) {
bg = nullptr;
return;
}
bg = XCreateImage(display, v, depth,
ZPixmap, 0, (char *)fb, width, height, 32, 0
);
if(! bg) {
free(fb);
return;
}
if(! src) {
memset(fb, 0, size);
return;
}
u8int *rgb = src;
int zch = sch > 4 ? 4 : sch;
float xs = (float)sw / width;
float ys = (float)sh / height;
float fy = 0;
for(int y = 0; y < height; y ++) {
float fx = 0;
int d = 0;
int s = 0;
for (int x = 0; x < width; x ++) {
fb[d] = rgb[s];
for(int z = 1; z < zch; z ++) fb[d + z] = rgb[s + z];
fx += xs;
d += 4;
s = sch * (int)fx;
}
fy += ys;
fb += dline;
rgb = src + sline * (int)fy;
}
XPutImage(display, child, gCtx, bg, 0, 0, 0, 0, width, height);
}
void setBackGround(cv::Mat &cam){
return setBackGround((u8int *)cam.data,
cam.cols,
cam.rows,
cam.channels()
);
}
void bgRestore(int x0, int y0, int sw = 0, int sh = 0) {
if (x0 < width && y0 < height){
if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0;
if (x0 + sw >= width) sw = width - x0;
if (y0 + sh >= height) sh = height - y0;
if (sw > 0 && sh > 0) XPutImage(display, child, gCtx,
bg, x0, y0,
x0, y0, sw, sh
);
}
}
int main(int argc, char **argv){
if(argc < 2) {
printf("no file\n");
return 1;
}
cv::Mat jpeg = cv::imread(argv[1]);// 8UC3
display = XOpenDisplay(getenv("DISPLAY"));
if (! display) {
printf("X error\n");
return 3;
}
child = XCreateSimpleWindow(display,
XDefaultRootWindow(display),
0, 0, 600, 600,
0,// border width
WhitePixel(display, 0),
BlackPixel(display, 0)
);
XSetStandardProperties(display, child, "MyXapp",
"Icon", None, nullptr, 0, nullptr
);
gCtx = XCreateGC(display, child, 0, 0);
setColorMap(black , "#000000");
setColorMap(white , "#FFFFFF");
setColorMap(red , "#FF0000");
setColorMap(green , "#00FF00");
setColorMap(blue , "#0000FF");
unsigned char shape[8] = {0xff, 0xff,0xff, 0xff, 0xff, 0xff,0xff, 0xff};
unsigned char mask[8] = {0xff, 0xff,0xff, 0, 0, 0xff,0xff, 0xff};// 1: show, 0: hidden
Pixmap shapeid = XCreateBitmapFromData(display, child, (char *)shape, 8, 8);
Pixmap maskid = XCreateBitmapFromData(display, child, (char *)mask, 8, 8);
Cursor cursorID = XCreatePixmapCursor(display, shapeid, maskid, &green, &black, 0, 0);
XDefineCursor(display, child, cursorID);
XFreePixmap(display, shapeid);
XFreePixmap(display, maskid);
XFreeCursor(display, cursorID);
XSelectInput(display, child, ExposureMask | ButtonPressMask);
XMapWindow(display, child);
XFlush(display);
fgSetColor(red);
XEvent evt;
printf("press mouse right button to exit.\n");
while(true) {
XNextEvent(display, &evt);
if (evt.type == Expose) {
if(evt.xexpose.count > 0) continue; // until count = 0
setBackGround(jpeg);
int right = width - 1;
int down = height - 1;
int cx = width / 2;
int cy = height / 2;
drawLine(0, cy, right, cy);
drawLine(cx, 0, cx, down);
drawArc(0, 0, right, down, 0, 360);
drawRect(0, 0, right, down);
bgRestore(cx - 100, cy - 100, 200, 200);
}
if (evt.type == ButtonPress) {
if(evt.xbutton.button == 3) {
printf("press right\n");
break;
}
}
}
if (bg) XDestroyImage(bg);
XFreeGC(display, gCtx);
XDestroyWindow(display, child);
XCloseDisplay(display);
}
事先準備好一個 test.jpeg, 編譯程式並執行:
g++ main.cpp -lX11 `pkg-config --cflags --libs opencv4` && ./a.out test.jpeg
沒有留言:
張貼留言