1

I have a Canvas with the image, that I load via filedialog, how can I get the pixel array of this image? I need convert it to grayscale by converting every pixel using formula and load it back to the Canvas. Here the code:

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

I'm trying to get ImageData, but here's empty I read that Canvas contain PixelArray, but I don't know how to get it. Thank you.

1 Answer 1

3

To access the rgba values

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

You have to requestPaint() in onClicked slot of Button

Sign up to request clarification or add additional context in comments.

3 Comments

I guess there is one thing missing: "[...] and load it back to the Canvas."
Thank you, but it works so slow, I need to send it to the Python side
You should be passing ar to drawImage not ar.data so it should be ctx.drawImage(ar, 0, 0);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.