Qt源码分析--QImage(4)

59 篇文章 1 订阅
37 篇文章 1 订阅

官方的例子:

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;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天进步2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值