Qt源码分析--QImage(8)

本文介绍了如何在QImage中设置每米像素数(dotsPerMeterX和dotsPerMeterY),以及如何使用fill函数填充颜色,包括不同深度格式的处理。重点在于理解图像分辨率和像素密度对绘图的影响及像素操作技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.void setDotsPerMeterX(int);

设置每米有多少个像素

/*!
    Sets the number of pixels that fit horizontally in a physical
    meter, to \a x.
    Together with dotsPerMeterY(), this number defines the intended
    scale and aspect ratio of the image, and determines the scale
    at which QPainter will draw graphics on the image. It does not
    change the scale or aspect ratio of the image when it is rendered
    on other paint devices.
    \sa dotsPerMeterX(), {QImage#Image Information}{Image Information}
*/
void QImage::setDotsPerMeterX(int x)
{
    if (!d || !x)
        return;
    detach();
    if (d)
        d->dpmx = x;
}

2.void setDotsPerMeterY(int);

/*!
    Sets the number of pixels that fit vertically in a physical meter,
    to \a y.
    Together with dotsPerMeterX(), this number defines the intended
    scale and aspect ratio of the image, and determines the scale
    at which QPainter will draw graphics on the image. It does not
    change the scale or aspect ratio of the image when it is rendered
    on other paint devices.
    \sa dotsPerMeterY(), {QImage#Image Information}{Image Information}
*/
void QImage::setDotsPerMeterY(int y)
{
    if (!d || !y)
        return;
    detach();
    if (d)
        d->dpmy = y;
}

3.void fill(const QColor &color);

/*!
    \fn void QImage::fill(const QColor &color)
    \overload
    Fills the entire image with the given \a color.
    If the depth of the image is 1, the image will be filled with 1 if
    \a color equals Qt::color1; it will otherwise be filled with 0.
    If the depth of the image is 8, the image will be filled with the
    index corresponding the \a color in the color table if present; it
    will otherwise be filled with 0.
    \since 4.8
*/
void QImage::fill(const QColor &color)
{
    if (!d)
        return;
    detach();
    // In case we run out of memory
    if (!d)
        return;
    QRgba64 opaque = color.rgba64();
    opaque.setAlpha(65535);
    switch (d->format) {
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
        fill(color.rgba());
        break;
    case QImage::Format_ARGB32_Premultiplied:
        fill(qPremultiply(color.rgba()));
        break;
    case QImage::Format_RGBX8888:
        fill(ARGB2RGBA(color.rgba() | 0xff000000));
        break;
    case QImage::Format_RGBA8888:
        fill(ARGB2RGBA(color.rgba()));
        break;
    case QImage::Format_RGBA8888_Premultiplied:
        fill(ARGB2RGBA(qPremultiply(color.rgba())));
        break;
    case QImage::Format_BGR30:
        fill(qConvertRgb64ToRgb30<PixelOrderBGR>(opaque));
        break;
    case QImage::Format_RGB30:
        fill(qConvertRgb64ToRgb30<PixelOrderRGB>(opaque));
        break;
    case QImage::Format_RGB16:
        fill((uint) qConvertRgb32To16(color.rgba()));
        break;
    case QImage::Format_Indexed8: {
        uint pixel = 0;
        for (int i=0; i<d->colortable.size(); ++i) {
            if (color.rgba() == d->colortable.at(i)) {
                pixel = i;
                break;
            }
        }
        fill(pixel);
        break;
    }
    case QImage::Format_Mono:
    case QImage::Format_MonoLSB:
        if (color == Qt::color1)
            fill((uint) 1);
        else
            fill((uint) 0);
        break;
    case QImage::Format_RGBX64:
        qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), opaque,
                             0, 0, d->width, d->height, d->bytes_per_line);
        break;
    case QImage::Format_RGBA64:
        qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), color.rgba64(),
                             0, 0, d->width, d->height, d->bytes_per_line);
        break;
    case QImage::Format_RGBA64_Premultiplied:
        qt_rectfill<quint64>(reinterpret_cast<quint64 *>(d->data), color.rgba64().premultiplied(),
                             0, 0, d->width, d->height, d->bytes_per_line);
        break;
    default: {
        QPainter p(this);
        p.setCompositionMode(QPainter::CompositionMode_Source);
        p.fillRect(rect(), color);
    }}
}

/*!
    \fn void QImage::fill(uint pixelValue)
    Fills the entire image with the given \a pixelValue.
    If the depth of this image is 1, only the lowest bit is used. If
    you say fill(0), fill(2), etc., the image is filled with 0s. If
    you say fill(1), fill(3), etc., the image is filled with 1s. If
    the depth is 8, the lowest 8 bits are used and if the depth is 16
    the lowest 16 bits are used.
    If the image depth is higher than 32bit the result is undefined.
    \note There are no corresponding value getter, though QImage::pixelIndex()
    will return the same value for indexed formats, and QImage::pixel() for
    RGB32, ARGB32, and ARGB32PM formats.
    \sa depth(), {QImage#Image Transformations}{Image Transformations}
*/
void QImage::fill(uint pixel)
{
    if (!d)
        return;
    detach();
    // In case detach() ran out of memory
    if (!d)
        return;
    if (d->depth == 1 || d->depth == 8) {
        int w = d->width;
        if (d->depth == 1) {
            if (pixel & 1)
                pixel = 0xffffffff;
            else
                pixel = 0;
            w = (w + 7) / 8;
        } else {
            pixel &= 0xff;
        }
        qt_rectfill<quint8>(d->data, pixel, 0, 0,
                            w, d->height, d->bytes_per_line);
        return;
    } else if (d->depth == 16) {
        if (d->format == Format_RGB444)
            pixel |= 0xf000;
        qt_rectfill<quint16>(reinterpret_cast<quint16*>(d->data), pixel,
                             0, 0, d->width, d->height, d->bytes_per_line);
        return;
    } else if (d->depth == 24) {
        if (d->format == Format_RGB666)
            pixel |= 0xfc0000;
        qt_rectfill<quint24>(reinterpret_cast<quint24*>(d->data), pixel,
                             0, 0, d->width, d->height, d->bytes_per_line);
        return;
    } else if (d->depth == 64) {
        qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), QRgba64::fromArgb32(pixel),
                             0, 0, d->width, d->height, d->bytes_per_line);
        return;
    }
    if (d->format == Format_RGB32)
        pixel |= 0xff000000;
    if (d->format == Format_RGBX8888)
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
        pixel |= 0xff000000;
#else
        pixel |= 0x000000ff;
#endif
    if (d->format == Format_BGR30 || d->format == Format_RGB30)
        pixel |= 0xc0000000;
    qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
                      0, 0, d->width, d->height, d->bytes_per_line);
}

template <class T> static
inline void qt_rectfill(T *dest, T value,
                        int x, int y, int width, int height, qsizetype stride)
{
    char *d = reinterpret_cast<char*>(dest + x) + y * stride;
    if (uint(stride) == (width * sizeof(T))) {
        qt_memfill(reinterpret_cast<T*>(d), value, qsizetype(width) * height);
    } else {
        for (int j = 0; j < height; ++j) {
            dest = reinterpret_cast<T*>(d);
            qt_memfill(dest, value, width);
            d += stride;
        }
    }
}

template<> inline void qt_memfill(quint8 *dest, quint8 color, qsizetype count)
{
    memset(dest, color, count);
}

先把QColor转成整数,然后调用fill(uint pixel)填充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天天进步2015

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

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

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

打赏作者

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

抵扣说明:

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

余额充值