官方的例子:
32-bit
QImage image(3, 3, QImage::Format_RGB32);
QRgb value;
value = qRgb(189, 149, 39); // 0xffbd9527
image.setPixel(1, 1, value);
value = qRgb(122, 163, 39); // 0xff7aa327
image.setPixel(0, 1, value);
image.setPixel(1, 0, value);
value = qRgb(237, 187, 51); // 0xffedba31
image.setPixel(2, 1, value);
8-bit
QImage image(3, 3, QImage::Format_Indexed8);
QRgb value;
value = qRgb(122, 163, 39); // 0xff7aa327
image.setColor(0, value);
value = qRgb(237, 187, 51); // 0xffedba31
image.setColor(1, value);
value = qRgb(189, 149, 39); // 0xffbd9527
image.setColor(2, value);
image.setPixel(0, 1, 0);
image.setPixel(1, 0, 0);
image.setPixel(1, 1, 2);
image.setPixel(2, 1, 1);
下面讲一下例子中用到的函数。
1.void QImage::setPixel(const QPoint &pt, uint index_or_rgb);
inline void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.x(), pt.y(), index_or_rgb); }
void QImage::setPixel(int x, int y, uint index_or_rgb)
{
if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
qWarning("QImage::setPixel: coordinate (%d,%d) out of range", x, y);
return;
}
// detach is called from within scanLine
uchar * s = scanLine(y);
switch(d->format) {
case Format_Mono:
case Format_MonoLSB:
if (index_or_rgb > 1) {
qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
} else if (format() == Format_MonoLSB) {
if (index_or_rgb==0)
*(s + (x >> 3)) &= ~(1 << (x & 7));
else
*(s + (x >> 3)) |= (1 << (x & 7));
} else {
if (index_or_rgb==0)
*(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
else
*(s + (x >> 3)) |= (1 << (7-(x & 7)));
}
return;
case Format_Indexed8:
if (index_or_rgb >= (uint)d->colortable.size()) {
qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
return;
}
s[x] = index_or_rgb;
return;
case Format_RGB32:
//make sure alpha is 255, we depend on it in qdrawhelper for cases
// when image is set as a texture pattern on a qbrush
((uint *)s)[x] = 0xff000000 | index_or_rgb;
return;
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
((uint *)s)[x] = index_or_rgb;
return;
case Format_RGB16:
((quint16 *)s)[x] = qConvertRgb32To16(index_or_rgb);
return;
case Format_RGBX8888:
((uint *)s)[x] = ARGB2RGBA(0xff000000 | index_or_rgb);
return;
case Format_RGBA8888:
case Format_RGBA8888_Premultiplied:
((uint *)s)[x] = ARGB2RGBA(index_or_rgb);
return;
case Format_BGR30:
((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderBGR>(index_or_rgb);
return;
case Format_A2BGR30_Premultiplied:
((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderBGR>(index_or_rgb);
return;
case Format_RGB30:
((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderRGB>(index_or_rgb);
return;
case Format_A2RGB30_Premultiplied:
((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderRGB>(index_or_rgb);
return;
case Format_RGBA64:
case Format_RGBA64_Premultiplied:
((QRgba64 *)s)[x] = QRgba64::fromArgb32(index_or_rgb);
return;
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
return;
default:
break;
}
const QPixelLayout *layout = &qPixelLayouts[d->format];
if (!hasAlphaChannel())
layout->storeFromRGB32(s, &index_or_rgb, x, 1, nullptr, nullptr);
else
layout->storeFromARGB32PM(s, &index_or_rgb, x, 1, nullptr, nullptr);
}
2.void setColor(int i, QRgb c);
void QImage::setColor(int i, QRgb c)
{
if (!d)
return;
if (i < 0 || d->depth > 8 || i >= 1<<d->depth) {
qWarning("QImage::setColor: Index out of bound %d", i);
return;
}
detach();
// In case detach() run out of memory
if (!d)
return;
if (i >= d->colortable.size())
setColorCount(i+1);
d->colortable[i] = c;
d->has_alpha_clut |= (qAlpha(c) != 255);
}
void QImage::setColorCount(int colorCount)
{
if (!d) {
qWarning("QImage::setColorCount: null image");
return;
}
detach();
// In case detach() ran out of memory
if (!d)
return;
if (colorCount == d->colortable.size())
return;
if (colorCount <= 0) { // use no color table
d->colortable.clear();
return;
}
int nc = d->colortable.size();
d->colortable.resize(colorCount);
for (int i = nc; i < colorCount; ++i)
d->colortable[i] = 0;
}
3.void QImage::setPixelColor(const QPoint &pt, const QColor &c)
void QImage::setPixelColor(int x, int y, const QColor &color)
{
if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
qWarning("QImage::setPixelColor: coordinate (%d,%d) out of range", x, y);
return;
}
if (!color.isValid()) {
qWarning("QImage::setPixelColor: color is invalid");
return;
}
// QColor is always unpremultiplied
QRgba64 c = color.rgba64();
if (!hasAlphaChannel())
c.setAlpha(65535);
else if (qPixelLayouts[d->format].premultiplied)
c = c.premultiplied();
// detach is called from within scanLine
uchar * s = scanLine(y);
switch (d->format) {
case Format_Mono:
case Format_MonoLSB:
case Format_Indexed8:
qWarning("QImage::setPixelColor: called on monochrome or indexed format");
return;
case Format_BGR30:
((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c) | 0xc0000000;
return;
case Format_A2BGR30_Premultiplied:
((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c);
return;
case Format_RGB30:
((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c) | 0xc0000000;
return;
case Format_A2RGB30_Premultiplied:
((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
return;
case Format_RGBX64:
case Format_RGBA64:
case Format_RGBA64_Premultiplied:
((QRgba64 *)s)[x] = c;
return;
default:
setPixel(x, y, c.toArgb32());
return;
}
}
4. const uchar *scanLine(int) const;
const uchar *QImage::scanLine(int i) const
{
if (!d)
return nullptr;
Q_ASSERT(i >= 0 && i < height());
return d->data + i * d->bytes_per_line;
}