📄 qimage.cpp
字号:
Use the invertPixels() function that takes a QImage::InvertMode parameter instead.*//*! \fn QImage::Endian QImage::systemByteOrder() Determines the host computer byte order. Returns QImage::LittleEndian (LSB first) or QImage::BigEndian (MSB first). This function is no longer relevant for QImage. Use QSysInfo instead.*/// Windows defines these#if defined(write)# undef write#endif#if defined(close)# undef close#endif#if defined(read)# undef read#endif/*! Resizes the color table to contain \a numColors entries. If the color table is expanded, all the extra colors will be set to transparent (i.e qRgba(0, 0, 0, 0)). \sa numColors(), colorTable(), {QImage#Image Transformations}{Image Transformations}*/void QImage::setNumColors(int numColors){ if (!d) return; detach(); if (numColors == d->colortable.size()) return; if (numColors <= 0) { // use no color table d->colortable = QVector<QRgb>(); return; } int nc = d->colortable.size(); d->colortable.resize(numColors); for (int i = nc; i < numColors; ++i) d->colortable[i] = 0;}/*! Returns the format of the image. \sa {QImage#Image Formats}{Image Formats}*/QImage::Format QImage::format() const{ return d ? d->format : Format_Invalid;}#ifdef QT3_SUPPORT/*! Returns true if alpha buffer mode is enabled; otherwise returns false. Use the hasAlphaChannel() function instead.*/bool QImage::hasAlphaBuffer() const{ return d && (d->format != Format_RGB32)#ifdef Q_WS_QWS && (d->format != Format_RGB16)#endif ;}/*! Enables alpha buffer mode if \a enable is true, otherwise disables it. The alpha buffer is used to set a mask when a QImage is translated to a QPixmap. If a monochrome or indexed 8-bit image has alpha channels in their color tables they will automatically detect that they have an alpha channel, so this function is not required. To force alpha channels on 32-bit images, use the convertToFormat() function.*/void QImage::setAlphaBuffer(bool enable){ if (!d || d->format == Format_Mono || d->format == Format_MonoLSB || d->format == Format_Indexed8) return; if (enable && (d->format == Format_ARGB32 || d->format == Format_ARGB32_Premultiplied)) return; if (!enable && d->format == Format_RGB32) return; detach(); d->format = (enable ? Format_ARGB32 : Format_RGB32);}/*! \fn bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder) Sets the image \a width, \a height, \a depth, its number of colors (in \a numColors), and bit order. Returns true if successful, or false if the parameters are incorrect or if memory cannot be allocated. The \a width and \a height is limited to 32767. \a depth must be 1, 8, or 32. If \a depth is 1, \a bitOrder must be set to either QImage::LittleEndian or QImage::BigEndian. For other depths \a bitOrder must be QImage::IgnoreEndian. This function allocates a color table and a buffer for the image data. The image data is not initialized. The image buffer is allocated as a single block that consists of a table of scanLine() pointers (jumpTable()) and the image data (bits()). Use a QImage constructor instead.*/bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder){ if (d && !d->ref.deref()) delete d; d = QImageData::create(QSize(width, height), formatFor(depth, bitOrder), numColors); return true;}/*! \fn bool QImage::create(const QSize& size, int depth, int numColors, Endian bitOrder) \overload The width and height are specified in the \a size argument. Use a QImage constructor instead.*/bool QImage::create(const QSize& size, int depth, int numColors, QImage::Endian bitOrder){ if (d && !d->ref.deref()) delete d; d = QImageData::create(size, formatFor(depth, bitOrder), numColors); return true;}#endif // QT3_SUPPORT/***************************************************************************** Internal routines for converting image depth. *****************************************************************************/typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags){ Q_ASSERT(src->format == QImage::Format_ARGB32); Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); Q_ASSERT(src->nbytes == dest->nbytes); Q_ASSERT(src->bytes_per_line == dest->bytes_per_line); const QRgb *src_data = (QRgb *) src->data; const QRgb *end = src_data + (src->nbytes>>2); QRgb *dest_data = (QRgb *) dest->data; while (src_data < end) { *dest_data = PREMUL(*src_data); ++src_data; ++dest_data; }}static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags){ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); Q_ASSERT(dest->format == QImage::Format_ARGB32); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); Q_ASSERT(src->nbytes == dest->nbytes); Q_ASSERT(src->bytes_per_line == dest->bytes_per_line); const QRgb *src_data = (QRgb *) src->data; const QRgb *end = src_data + (src->nbytes>>2); QRgb *dest_data = (QRgb *) dest->data; while (src_data < end) { *dest_data = INV_PREMUL(*src_data); ++src_data; ++dest_data; }}static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags){ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); Q_ASSERT(dest->format == QImage::Format_RGB32); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); Q_ASSERT(src->nbytes == dest->nbytes); Q_ASSERT(src->bytes_per_line == dest->bytes_per_line); const QRgb *src_data = (QRgb *) src->data; const QRgb *end = src_data + (src->nbytes>>2); QRgb *dest_data = (QRgb *) dest->data; while (src_data < end) { *dest_data = 0xff000000 | INV_PREMUL(*src_data); ++src_data; ++dest_data; }}static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags){ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB); Q_ASSERT(dest->format == QImage::Format_Mono || dest->format == QImage::Format_MonoLSB); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); Q_ASSERT(src->nbytes == dest->nbytes); Q_ASSERT(src->bytes_per_line == dest->bytes_per_line); dest->colortable = src->colortable; const uchar *src_data = src->data; const uchar *end = src->data + src->nbytes; uchar *dest_data = dest->data; while (src_data < end) { *dest_data = bitflip[*src_data]; ++src_data; ++dest_data; }}static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags){ Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); Q_ASSERT(src->nbytes == dest->nbytes); const uint *src_data = (const uint *)src->data; const uint *end = (const uint *)(src->data + src->nbytes); uint *dest_data = (uint *)dest->data; while (src_data < end) { *dest_data = *src_data | 0xff000000; ++src_data; ++dest_data; }}static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format){ QVector<QRgb> colorTable = ctbl; if (format == QImage::Format_RGB32) { // check if the color table has alpha for (int i = 0; i < colorTable.size(); ++i) if (qAlpha(colorTable.at(i) != 0xff)) colorTable[i] = colorTable.at(i) | 0xff000000; } else if (format == QImage::Format_ARGB32_Premultiplied) { // check if the color table has alpha for (int i = 0; i < colorTable.size(); ++i) colorTable[i] = PREMUL(colorTable.at(i)); } return colorTable;}//// dither_to_1: Uses selected dithering algorithm.//static void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha){ Q_ASSERT(src->width == dst->width); Q_ASSERT(src->height == dst->height); Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB); dst->colortable.clear(); dst->colortable.append(0xffffffff); dst->colortable.append(0xff000000); enum { Threshold, Ordered, Diffuse } dithermode; if (fromalpha) { if ((flags & Qt::AlphaDither_Mask) == Qt::DiffuseAlphaDither) dithermode = Diffuse; else if ((flags & Qt::AlphaDither_Mask) == Qt::OrderedAlphaDither) dithermode = Ordered; else dithermode = Threshold; } else { if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither) dithermode = Threshold; else if ((flags & Qt::Dither_Mask) == Qt::OrderedDither) dithermode = Ordered; else dithermode = Diffuse; } int w = src->width; int h = src->height; int d = src->depth; uchar gray[256]; // gray map for 8 bit images bool use_gray = (d == 8); if (use_gray) { // make gray map if (fromalpha) { // Alpha 0x00 -> 0 pixels (white) // Alpha 0xFF -> 1 pixels (black) for (int i = 0; i < src->colortable.size(); i++) gray[i] = (255 - (src->colortable.at(i) >> 24)); } else { // Pixel 0x00 -> 1 pixels (black) // Pixel 0xFF -> 0 pixels (white) for (int i = 0; i < src->colortable.size(); i++) gray[i] = qGray(src->colortable.at(i)); } } uchar *dst_data = dst->data; int dst_bpl = dst->bytes_per_line; const uchar *src_data = src->data; int src_bpl = src->bytes_per_line; switch (dithermode) { case Diffuse: { int *line1 = new int[w]; int *line2 = new int[w]; int bmwidth = (w+7)/8; int *b1, *b2; int wbytes = w * (d/8); register const uchar *p = src->data; const uchar *end = p + wbytes; b2 = line2; if (use_gray) { // 8 bit image while (p < end) *b2++ = gray[*p++]; } else { // 32 bit image if (fromalpha) { while (p < end) { *b2++ = 255 - (*(uint*)p >> 24); p += 4; } } else { while (p < end) { *b2++ = qGray(*(uint*)p); p += 4; } } } for (int y=0; y<h; y++) { // for each scan line... int *tmp = line1; line1 = line2; line2 = tmp; bool not_last_line = y < h - 1; if (not_last_line) { // calc. grayvals for next line p = src->data + (y+1)*src->bytes_per_line; end = p + wbytes; b2 = line2; if (use_gray) { // 8 bit image while (p < end) *b2++ = gray[*p++]; } else { // 24 bit image if (fromalpha) { while (p < end) { *b2++ = 255 - (*(uint*)p >> 24); p += 4; } } else { while (p < end) { *b2++ = qGray(*(uint*)p); p += 4; } } } } int err; uchar *p = dst->data + y*dst->bytes_per_line; memset(p, 0, bmwidth); b1 = line1; b2 = line2; int bit = 7; for (int x=1; x<=w; x++) { if (*b1 < 128) { // black pixel err = *b1++; *p |= 1 << bit; } else { // white pixel err = *b1++ - 255; } if (bit == 0) { p++; bit = 7; } else { bit--; } if (x < w) *b1 += (err*7)>>4; // spread error to right pixel if (not_last_line) { b2[0] += (err*5)>>4; // pixel below if (x > 1) b2[-1] += (err*3)>>4; // pixel below left if (x < w) b2[1] += err>>4; // pixel below right } b2++; } } delete [] line1; delete [] line2; } break; case Ordered: { memset(dst->data, 0, dst->nbytes); if (d == 32) { for (int i=0; i<h; i++) { const uint *p = (const uint *)src_data; const uint *end = p + w; uchar *m = dst_data; int bit = 7; int j = 0; if (fromalpha) { while (p < end) { if ((*p++ >> 24) >= qt_bayer_matrix[j++&15][i&15]) *m |= 1 << bit; if (bit == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -