我如何从QML画布获取像素阵列?

时间:2018-07-18 17:30:01

标签: qt canvas qml

我有一个通过文件对话框加载的图像画布,如何获取该图像的像素阵列? 我需要使用公式将每个像素转换为灰度并将其加载回Canvas。 这里的代码:

import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.2
import QtQuick.Dialogs 1.0

ApplicationWindow {
    id: window
    visible: true
    width: 1000
    height: 750
    Material.theme: Material.Dark
    Material.background: "#2C303A"
    Material.accent: "#65B486"
    Material.foreground: "#efefef"

    GridLayout {
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 9

        columns: 4
        rows: 3
        rowSpacing: 10
        columnSpacing: 10
        Canvas {
            id: canvas
            height: window.height - 15
            Layout.columnSpan: 4
            Layout.fillWidth: true
            property bool loaded: false
            property var filepath: ''

            onDrawChanged: requestPaint()
            onFilepathChanged: {
                loadImage(filepath)
            }
            onImageLoaded: {
                loaded = true
                requestPaint()
            }
            onPaint: {
                if (loaded) {
                    var ctx = getContext("2d");
                    ctx.drawImage(filepath, 0, 0, width, height)
                }
                if (to_grayscale) {
                    var ctx = getContext("2d");
                    var ar = ctx.getImageData(0, 0, width, height).data
                    for(var i in ar){
                        print(i)
                    }
                }
            }
        }

        FileDialog {
            id: fileDialog
            title: "Please choose a file"
            nameFilters: ["Image files (*.jpg *.png *.jpeg)"]
            onAccepted: {
                console.log("You chose: " + fileDialog.fileUrls)
                canvas.filepath = fileDialog.fileUrls
                canvas.requestPaint()
            }
            onRejected: {
                console.log("Canceled")
            }
        }
        Drawer {
            id: drawer
            visible: true
            modal: false
            width: 0.33 * window.width
            height: window.height
            GridLayout {
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.margins: 9

                columns: 2
                rows: 3
                rowSpacing: 10
                columnSpacing: 10
                Button {
                    text: 'Load image'
                    onClicked: fileDialog.visible = true
                }

                Button {
                    text: 'RGB to Grayscale'
                    onClicked: canvas.draw = true
                }
            }       
        }
    }
    }

我正在尝试获取ImageData,但是这里是空的 我读过Canvas包含PixelArray,但我不知道如何获得它。 谢谢。

1 个答案:

答案 0 :(得分:1)

访问rgba值

            var ar = ctx.getImageData(0, 0, width, height);

            for( var x=0; x < ar.data.length; x=x+4 )
            {

                // To read RGBA values
                var red   =  ar.data[x];
                var green =  ar.data[x + 1];
                var blue  =  ar.data[x + 2];
                var alpha =  ar.data[x + 3];

                console.log(red + ", " + green + ", " + blue + ", " + alpha );

                // To convert to grey scale, modify rgba according to your formula
                ar.data[x]     = 0.2126 *ar.data[x]  + 0.7152* ar.data[x+1]  + 0.0722 *ar.data[x+2];
                ar.data[x+1]   = 0.2126 *ar.data[x]  + 0.7152* ar.data[x+1]  + 0.0722 *ar.data[x+2];
                ar.data[x+2]   = 0.2126 *ar.data[x]  + 0.7152* ar.data[x+1]  + 0.0722 *ar.data[x+2];
                ar.data[x+3]   =  255;                                      

            }

            // update the canvas with new data
            ctx.drawImage(ar.data, 0, 0);

您必须requestPaint()在Button的onClicked插槽中