لماذا يتم تعيين قيم CanVaspixelarray من HTML5 بطيئًا بشكل يبعث على السخرية وكيف يمكنني القيام بذلك بشكل أسرع؟

StackOverflow https://stackoverflow.com/questions/2573212

سؤال

أحاول القيام ببعض المؤثرات المرئية الديناميكية باستخدام معالجة بكسل HTML 5 ، لكنني أواجه مشكلة حيث يكون وضع البيكسلات في Canvaspixelarray بطيئًا بشكل يبعث على السخرية.

على سبيل المثال إذا كان لدي رمز مثل:

imageData = ctx.getImageData(0, 0, 500, 500);

for (var i = 0; i < imageData.length; i += 4){
    imageData.data[i] = buffer[i];
    imageData.data[i + 1] = buffer[i + 1];
    imageData.data[i + 2] = buffer[i + 2];
}

ctx.putImageData(imageData, 0, 0);

يتكشف التنميط مع Chrome ، فإنه يعمل بنسبة 44 ٪ من الكود التالي حيث لا يتم استخدام Canvaspixelarray.

tempArray = new Array(500 * 500 * 4);
imageData = ctx.getImageData(0, 0, 500, 500);

for (var i = 0; i < imageData.length; i += 4){
    tempArray[i] = buffer[i];
    tempArray[i + 1] = buffer[i + 1];
    tempArray[i + 2] = buffer[i + 2];
}

ctx.putImageData(imageData, 0, 0);

أظن أن سبب هذا التباطؤ يرجع إلى التحويل بين زوجي JavaScript والأعداد الصحيحة الداخلية 8Bit غير الموقعة ، التي يستخدمها Canvaspixelarray.

  1. هل هذا تخمين صحيح؟
  2. هل هناك على أي حال لتقليل الوقت الذي يقضيه في وضع القيم في canvaspixelarray؟
هل كانت مفيدة؟

المحلول

حاول تخزين المؤقت إشارة إلى data صفيف بكسل. يمكن أن يعزى تباطؤك إلى وصول الممتلكات الإضافية إلى imageData.data. يرى هذه المقالة لمزيد من التفسير.

على سبيل المثال ، يجب أن يكون هذا أسرع من أن لديك حاليًا.

var imageData = ctx.getImageData(0, 0, 500, 500),
    data = imageData.data,
    len = data.length;

for (var i = 0; i < len; i += 4){
 data[i] = buffer[i];
 data[i + 1] = buffer[i + 1];
 data[i + 2] = buffer[i + 2];
}

ctx.putImageData(imageData, 0, 0);

نصائح أخرى

لا أعرف ما إذا كان هذا يساعدك لأنك تريد معالجة وحدات البكسل ، لكن بالنسبة لي ، في Firefox 3.6.8 ، كانت الدعوة إلى Putimagedata بطيئة جدًا ، دون القيام بأي تلاعب بكسل. في حالتي ، أردت فقط استعادة نسخة سابقة من الصورة التي تم حفظها مع GetImagedata. بطئ جدا.

بدلاً من ذلك ، حصلت على العمل بشكل جيد باستخدام Todataurl/DrawImage بدلاً من ذلك. بالنسبة لي ، إنه يعمل بسرعة كافية بحيث يمكنني تسميته في التعامل مع حدث Mousemove:

للحفظ:

savedImage = new Image()  
savedImage.src = canvas.toDataURL("image/png")

لاستعادة:

ctx = canvas.getContext('2d')  
ctx.drawImage(savedImage,0,0)

يبدو أنك تفعل نوعًا من "الصراخ" ، لذلك ربما drawimage أو All-on-once putimagedata يمكن ان تساعد. يميل حلقات ربع مليون مرة لنسخ وحدات البكسل بشكل فردي ، بدلاً من استخدام العمليات "الضخمة" الضخمة ، إلى أن تكون أبطأ بكثير-وليس فقط في JavaScript ؛-).

من الغريب أن الحلقات من خلال صفائف الكائن ثنائية الأبعاد أسرع من calcs صفيف 1D ولا توجد كائنات. وفقًا لذلك ، ومعرفة ما إذا كان ذلك يساعد (في اختباراتي ، كان 20x أسرع).

(رؤساء UP: هذا البرنامج النصي يمكن أن يصطدم متصفحك! إذا قمت بتشغيله ، اجلس ضيقة لبضع دقائق واتركه يفعل شيئًا)http://jsfiddle.net/hc52jx04/16/

function arrangeImageData (target) {

var imageCapture = target.context.getImageData(0, 0, target.width, target.height);
var imageData = {
    data: []
};
imageData.data[0] = [];
var x = 0;
var y = 0;
var imageLimit = imageCapture.data.length;

for (var index = 0; index < imageLimit; index += 4) {

    if (x == target.width) {
        y++;
        imageData.data[y] = [];
        x = 0;
    }

    imageData.data[y][x] = {
        red: imageCapture.data[index],
        green: imageCapture.data[index + 1],
        blue: imageCapture.data[index + 2],
        alpha: imageCapture.data[index + 3]
    };
    x++;
}
return imageData;

}


function codifyImageData (target, data) {

var imageData = data.data;

var index = 0;
var codedImage = target.context.createImageData(target.width, target.height);

for (var y = 0; y < target.height; y++) {

    for (var x = 0; x < target.width; x++) {

        codedImage.data[index] = imageData[y][x].red;
        index++;
        codedImage.data[index] = imageData[y][x].green;
        index++;
        codedImage.data[index] = imageData[y][x].blue;
        index++;
        codedImage.data[index] = imageData[y][x].alpha;
        index++;
    }

}

return codedImage;

}

معلومات اكثر: http://discourse.wicg.io/t/why-astraight-array-for-canvas-getimagedata/1020/6

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top