【问题标题】:Image inside Window is ugly窗口内的图像很难看
【发布时间】:2015-11-08 22:54:52
【问题描述】:

这是一个非常简单的 QML 代码

Window {
    id: window
    width: 800
    height: 600
    visible: true

    Image {
        id: image
        source: "myImage.png"
    }
}

图像需要完美显示像素。但是有一个默认的抗锯齿功能会使图像变得难看。我将渲染与其他图像阅读器进行了比较,显然存在问题。

我试过了(不是先同时再合并):

antialiasing: false
smooth: false
autoTransform: false
fillMode: Image.PreserveAspectFit
fillMode: Image.Pad

没有用,图像保持模糊丑陋

也许 Window 组件正在做某事或 QmlEngine,我正在像这样加载我的 qml:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/ui.qml"));
    return app.exec();
}

这是一个测试项目:https://github.com/BlueMagma2/imageIssue

编辑:

自从我提出这个问题后,我又测试了一些东西:

Linux 和 Windows 上的 Qbs 和 QMake 存在问题。

从 qrc 加载图片或从应用程序外部加载图片具有相同的结果。

较小的图像可以正常工作。所以可能是图像的大小造成了真正的麻烦(256 * 16064)

【问题讨论】:

  • 尝试将widthheight 明确指定给您的Image,确保它们与源png 匹配。
  • 已经试过了,还是不行。
  • 这很有趣。我不记得有这样的问题。您能否在 GitHub 或您喜欢的任何地方提供一个完整的、可运行的代码示例,以便我们尝试一下?谢谢。
  • 您是如何构建您的项目的?我无法在 Qt Creator 中编译它。但是,我通过创建新的 Qt Quick 项目、添加您的文件并用您的替换默认 main.cpp 来编译它。图像看起来正确。没有什么是模糊的。
  • 我用过Qbs,你用过QMake吗?那可能是问题所在?

标签: qt qml


【解决方案1】:

图像的大小是问题(256 x 16064),特别是:高度

不同高度的测试表明,在 8192px 高度之后的某处,移动和模糊效果开始破坏图像(有时图像甚至变黑)。

解决此问题的唯一方法是将图像切成更小的部分。

我使用 QQuickImageProvider 来完成,因为这个图像是一个图块集,所以我为每个图块 (32 x 32) 切割它。对于其他图像,最好选择更大的尺寸

class TileImageProvider : public QQuickImageProvider
{

public:
    TileImageProvider() : QQuickImageProvider(QQuickImageProvider::Image) {}

    QHash<QString, QImage> tilesetCache;

    virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize) {
        int width = 32;
        int height = 32;
        QStringList idData = id.split("/");
        int posX = idData.at(1).toInt();
        int posY = idData.at(2).toInt();
        if (size)
            *size = QSize(width, height);
        QImage image;
        if (!tilesetCache.contains(idData.at(0))) {
            image = QImage(":/" + idData.at(0));
            tilesetCache[idData.at(0)] = image;
        } else {
            image = tilesetCache[idData.at(0)];
        }
        return image.copy(posX * width, posY * height, width, height);
    }
};

您需要向引擎声明您的提供者:

QQmlApplicationEngine engine;
engine.addImageProvider(QLatin1String("tile"), new TileImageProvider);

这是一个如何从 QML 加载它的示例:

Grid {
    id: grid
    columns: 7;
    rows: 20;

    Repeater {
        model: grid.columns * grid.rows
        delegate: Image {
            id: image
            width: 32
            height: 32
            asynchronous: true
            source: "image://tile/image.png/" + posX + "/" + posY
            smooth: false
            antialiasing: false
            fillMode: Image.Pad;

            property int posX: index % grid.columns
            property int posY: (index - posX) / grid.columns
        }
    }
}

【讨论】:

    【解决方案2】:

    如果您使用的是 QtQuick 2.5,可以尝试 mipmap 选项。

    http://doc.qt.io/qt-5/qml-qtquick-image.html#mipmap-prop

    它不会是完美的像素,但它比使用平滑或抗锯齿属性要平滑得多。

    要做到完美像素,您需要知道确切的分辨率、像素密度等或您的目标设备。如果你不能保证这一点,那么你永远不会是像素完美的。

    【讨论】:

    • 我可以保证,我需要它是像素完美的。另外,我已经尝试过mipmap,结果完全一样
    • 我的目标设备是:我的屏幕,像素密度与它无关,因为我没有将其调整为特定的 dpi,我希望图像完全显示为像素大小我在应用程序中确实有确切的像素大小。
    • 我查看了您的 github 项目,发现您的图像非常高。我敢肯定,您不会一下子全部显示出来。您是否考虑过使用 sprite 引擎将图像分解为您想要在给定时间显示的部分?你用图像做什么?看起来像地图,准确吗?
    • 确实,这是一个tileset,每个32*32的方格可以和其他方格组合使用,创建2D地图。我在一个轻弹中使用它
    • 好的,那么回到使用精灵引擎的想法。我没有亲自使用它,所以我不能从经验中说出来,但看看这个:doc.qt.io/qt-5/qtquick-effects-sprites.html。有帮助吗?
    【解决方案3】:

    我遇到了与通过绑定定位的图像非常相似的问题。在谷歌搜索没有结果后,我尝试将 Math.round() 添加到坐标中,它有所帮助!

    handle: Image {
         id: thumb
         source: "thumb.png"
         x: Math.round( parent.leftPadding + parent.availableWidth / 2 - width / 2 )
         y: Math.round( parent.topPadding + parent.visualPosition * (parent.availableHeight - height) )
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多