Unsolved Predominant image colour expensive!
-
Hi All,
Using QtQuick 2.5 // Qt 5.5.1
I am trying to get the average colour from an image so i can display the colour in a container that is bigger than said image. This is working by loading in the source image to a Canvas then fetching the image data using getContext()-> getImageData
However the loop for CanvasImageData->data object is time consuming and seems to lockup the application. Now i have tried to move this into a workscript however it seems that Worker Script will not accept the data's type (data : object).
I could loop through the object to create an array but i feel this will also be time consuming and also make using Worker Script pointless. Before i pull my hair out i wanted to check i am not doing something stupid with parsing the data to the worker script!
Was hoping for suggestions of things to try or a point in the right direction
canvasPickedColour = "#ffffff" //Reset to force an onChanged signal. This is to prevent opening and closing same synopsis and not getting a colour change signal not being received ctx = colourCanvas.getContext("2d"); ctx.save(); ctx.drawImage(imageSource, 0, 0, canvasWidth, canvasHeight); canvasImageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight) var rgb = { r:255 ,g:255 ,b:255 } // Set a base colour as a fallback for non-compliant browsers var count = 0 var i = -4 var data = canvasImageData.data; var length = data.length; //log.out("length: " + length) while ((i += searchQuality * 4) < length) { count++; rgb.r += data[i]; rgb.g += data[i+1]; rgb.b += data[i+2]; } // floor the average values to give correct rgb values (ie: round number values) rgb.r = Math.floor(rgb.r/count); rgb.g = Math.floor(rgb.g/count); rgb.b = Math.floor(rgb.b/count); //Normalise the values from 0-255 to between 0 and 1.. log.out("before normalize -> rgb.r: " + rgb.r + ", rgb.g: " + rgb.g + ", rgb.b: " + rgb.b) rgb.r = normalize(rgb.r, 0 , 255) rgb.g = normalize(rgb.g, 0 , 255) rgb.b = normalize(rgb.b, 0 , 255) log.out("after normalize -> rgb.r: " + rgb.r + ", rgb.g: " + rgb.g + ", rgb.b: " + rgb.b) var dominantColor = Qt.rgba(rgb.r, rgb.g, rgb.b) log.out("dominantColor: " + dominantColor) canvasPickedColour = dominantColor ctx.restore(); function normalize(value, min, max) { var normalized = (value - min) / (max - min); return normalized; }
Cheers,
Rob.
-
@teh_raab said in Predominant image colour expensive!:
However the loop for CanvasImageData->data object is time consuming and seems to lockup the application.
Well how big is your
canvasImageData.data.length
? Big?! Because your loop is going to be busy throughout. -
The length is 884736.
My problem is that its locking up the GUI thread. I wanted to just take the data object returned from getImageData and parse it to a workscript for it to then loop through
Also note that i have a "searchQuality" variable that i have set to 20 so actually we only process every 20th pixel. Going any higher than this will increase the risk of showing a less predominant colour.
-
Do it in c++ and without
Canvas
, QtConcurrent will help you for making it asynchronous