📄 qpixmap_x11.cpp
字号:
++p; } ) break; case BPP16_555: CYCLE( quint16* dst16 = (quint16*)dst; for (int x=0; x<w; x++) { *dst16++ = ((*p >> 9) & 0x7c00) | ((*p >> 6) & 0x3e0) | ((*p >> 3) & 0x1f); ++p; } ) break; case BPP16_MSB: // 16 bit MSB CYCLE( for (int x=0; x<w; x++) { GET_PIXEL *dst++ = (pixel >> 8); *dst++ = pixel; } ) break; case BPP16_LSB: // 16 bit LSB CYCLE( for (int x=0; x<w; x++) { GET_PIXEL *dst++ = pixel; *dst++ = pixel >> 8; } ) break; case BPP24_888: // 24 bit MSB CYCLE( for (int x=0; x<w; x++) { *dst++ = qRed (*p); *dst++ = qGreen(*p); *dst++ = qBlue (*p++); } ) break; case BPP24_MSB: // 24 bit MSB CYCLE( for (int x=0; x<w; x++) { GET_PIXEL *dst++ = pixel >> 16; *dst++ = pixel >> 8; *dst++ = pixel; } ) break; case BPP24_LSB: // 24 bit LSB CYCLE( for (int x=0; x<w; x++) { GET_PIXEL *dst++ = pixel; *dst++ = pixel >> 8; *dst++ = pixel >> 16; } ) break; case BPP32_8888: CYCLE( memcpy(dst, p, w * 4); ) break; case BPP32_MSB: // 32 bit MSB CYCLE( for (int x=0; x<w; x++) { GET_PIXEL *dst++ = pixel >> 24; *dst++ = pixel >> 16; *dst++ = pixel >> 8; *dst++ = pixel; } ) break; case BPP32_LSB: // 32 bit LSB CYCLE( for (int x=0; x<w; x++) { GET_PIXEL *dst++ = pixel; *dst++ = pixel >> 8; *dst++ = pixel >> 16; *dst++ = pixel >> 24; } ) break; default: qFatal("Logic error 2"); } } xi->data = (char *)newbits; } if (d == 8 && !trucol) { // 8 bit pixmap int pop[256]; // pixel popularity if (image.numColors() == 0) image.setNumColors(1); const QImage &cimage = image; memset(pop, 0, sizeof(int)*256); // reset popularity array for (int i = 0; i < h; i++) { // for each scanline... const uchar* p = cimage.scanLine(i); const uchar *end = p + w; while (p < end) // compute popularity pop[*p++]++; } newbits = (uchar *)malloc(nbytes); // copy image into newbits Q_CHECK_PTR(newbits); if (!newbits) // no memory return QPixmap(); uchar* p = newbits; memcpy(p, cimage.bits(), nbytes); // copy image data into newbits /* * The code below picks the most important colors. It is based on the * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley. */ struct PIX { // pixel sort element uchar r,g,b,n; // color + pad int use; // popularity int index; // index in colormap int mindist; }; int ncols = 0; for (int i=0; i< cimage.numColors(); i++) { // compute number of colors if (pop[i] > 0) ncols++; } for (int i = cimage.numColors(); i < 256; i++) // ignore out-of-range pixels pop[i] = 0; // works since we make sure above to have at least // one color in the image if (ncols == 0) ncols = 1; PIX pixarr[256]; // pixel array PIX pixarr_sorted[256]; // pixel array (sorted) memset(pixarr, 0, ncols*sizeof(PIX)); PIX *px = &pixarr[0]; int maxpop = 0; int maxpix = 0; uint j = 0; QVector<QRgb> ctable = cimage.colorTable(); for (int i = 0; i < 256; i++) { // init pixel array if (pop[i] > 0) { px->r = qRed (ctable[i]); px->g = qGreen(ctable[i]); px->b = qBlue (ctable[i]); px->n = 0; px->use = pop[i]; if (pop[i] > maxpop) { // select most popular entry maxpop = pop[i]; maxpix = j; } px->index = i; px->mindist = 1000000; px++; j++; } } pixarr_sorted[0] = pixarr[maxpix]; pixarr[maxpix].use = 0; for (int i = 1; i < ncols; i++) { // sort pixels int minpix = -1, mindist = -1; px = &pixarr_sorted[i-1]; int r = px->r; int g = px->g; int b = px->b; int dist; if ((i & 1) || i<10) { // sort on max distance for (int j=0; j<ncols; j++) { px = &pixarr[j]; if (px->use) { dist = (px->r - r)*(px->r - r) + (px->g - g)*(px->g - g) + (px->b - b)*(px->b - b); if (px->mindist > dist) px->mindist = dist; if (px->mindist > mindist) { mindist = px->mindist; minpix = j; } } } } else { // sort on max popularity for (int j=0; j<ncols; j++) { px = &pixarr[j]; if (px->use) { dist = (px->r - r)*(px->r - r) + (px->g - g)*(px->g - g) + (px->b - b)*(px->b - b); if (px->mindist > dist) px->mindist = dist; if (px->use > mindist) { mindist = px->use; minpix = j; } } } } pixarr_sorted[i] = pixarr[minpix]; pixarr[minpix].use = 0; } QColormap cmap = QColormap::instance(pixmap.data->xinfo.screen()); uint pix[256]; // pixel translation table px = &pixarr_sorted[0]; for (int i = 0; i < ncols; i++) { // allocate colors QColor c(px->r, px->g, px->b); pix[px->index] = cmap.pixel(c); px++; } p = newbits; for (int i = 0; i < nbytes; i++) { // translate pixels *p = pix[*p]; p++; } } if (!xi) { // X image not created xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0); if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp ushort *p2; int p2inc = xi->bytes_per_line/sizeof(ushort); ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h); Q_CHECK_PTR(newerbits); if (!newerbits) // no memory return QPixmap(); uchar* p = newbits; for (int y = 0; y < h; y++) { // OOPS: Do right byte order!! p2 = newerbits + p2inc*y; for (int x = 0; x < w; x++) *p2++ = *p++; } free(newbits); newbits = (uchar *)newerbits; } else if (xi->bits_per_pixel != 8) { qWarning("QPixmap::fromImage: Display not supported " "(bpp=%d)", xi->bits_per_pixel); } xi->data = (char *)newbits; } pixmap.data->hd = (Qt::HANDLE)XCreatePixmap(X11->display, RootWindow(X11->display, pixmap.data->xinfo.screen()), w, h, dd); GC gc = XCreateGC(dpy, pixmap.data->hd, 0, 0); XPutImage(dpy, pixmap.data->hd, gc, xi, 0, 0, 0, 0, w, h); XFreeGC(dpy, gc); qSafeXDestroyImage(xi); pixmap.data->w = w; pixmap.data->h = h; pixmap.data->d = dd;#ifndef QT_NO_XRENDER if (X11->use_xrender) { XRenderPictFormat *format = pixmap.data->d == 1 ? XRenderFindStandardFormat(X11->display, PictStandardA1) : XRenderFindVisualFormat(X11->display, (Visual *) pixmap.data->xinfo.visual()); pixmap.data->picture = XRenderCreatePicture(X11->display, pixmap.data->hd, format, 0, 0); }#endif if (image.hasAlphaChannel()) { QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags)); pixmap.setMask(m); } return pixmap;}/*! \fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int width, int height) Creates and returns a pixmap constructed by grabbing the contents of the given \a window restricted by QRect(\a x, \a y, \a width, \a height). The arguments (\a{x}, \a{y}) specify the offset in the window, whereas (\a{width}, \a{height}) specify the area to be copied. If \a width is negative, the function copies everything to the right border of the window. If \a height is negative, the function copies everything to the bottom of the window. The window system identifier (\c WId) can be retrieved using the QWidget::winId() function. The rationale for using a window identifier and not a QWidget, is to enable grabbing of windows that are not part of the application, window system frames, and so on. The grabWindow() function grabs pixels from the screen, not from the window, i.e. if there is another window partially or entirely over the one you grab, you get pixels from the overlying window, too. The mouse cursor is generally not grabbed. Note on X11that if the given \a window doesn't have the same depth as the root window, and another window partially or entirely obscures the one you grab, you will \e not get pixels from the overlying window. The contents of the obscured areas in the pixmap will be undefined and uninitialized. \warning In general, grabbing an area outside the screen is not safe. This depends on the underlying window system. \sa grabWidget(), {Screenshot Example}*/QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h){ if (w == 0 || h == 0) return QPixmap(); Display *dpy = X11->display; XWindowAttributes window_attr; if (! XGetWindowAttributes(dpy, window, &window_attr)) return QPixmap(); if (w < 0) w = window_attr.width - x; if (h < 0) h = window_attr.height - y; // determine the screen int scr; for (scr = 0; scr < ScreenCount(dpy); ++scr) { if (window_attr.root == RootWindow(dpy, scr)) // found it break; } if (scr >= ScreenCount(dpy)) // sanity check return QPixmap(); // get the depth of the root window XWindowAttributes root_attr; if (! XGetWindowAttributes(dpy, window_attr.root, &root_attr)) return QPixmap(); if (window_attr.depth == root_attr.depth) { // if the depth of the specified window and the root window are the // same, grab pixels from the root window (so that we get the any // overlapping windows and window manager frames) // map x and y to the root window WId unused; if (! XTranslateCoordinates(dpy, window, window_attr.root, x, y, &x, &y, &unused)) return QPixmap(); window = window_attr.root;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -