2011-12-10 14 views
8

मैं थोड़ा HTML5 गेम कर रहा हूं और, मानचित्र की शुरुआत में अपने sprites लोड करते समय, मैं सभी छवियों पर GetImageData()/looping के साथ कुछ प्रसंस्करण करता हूं/PutImageData()।मोबाइल पर भयानक कैनवास GetImageData()/PutImageData() प्रदर्शन

यह मेरे पीसी पर शानदार रूप से बढ़िया काम करता है, हालांकि, मेरे सेल फोन पर यह बेहद धीमी है।

PC: 5-6 ms 
iPhone 4: 300-600 ms 
Android HTC Desire S: 2500-3000 ms 

मैं कुछ बहुत ही बुनियादी बेंच मार्किंग कर रहा हूँ, और दोनों GetImageData और PutImageData बहुत तेजी से चलाने के लिए, क्या समय लग रहा है सामग्री के माध्यम से पाशन है।

अब, स्पष्ट रूप से फोन पर मंदी की उम्मीद है, लेकिन 1000x थोड़ा अधिक लगता है, और लोडिंग में मेरे एचटीसी पर लगभग 4 मिनट लगते हैं, इसलिए यह काम नहीं करेगा। इसके अलावा, इस खेल में सब कुछ बहुत ही उचित गति से काम करता है (जिसका मुख्य कारण स्क्रीन हास्यास्पद छोटा होता है, लेकिन फिर भी यह एक सेल फोन पर जे एस के लिए आश्चर्यजनक रूप से ठीक काम करता है)


क्या मैं इस प्रक्रिया में कर रहा हूँ एक निश्चित स्तर पर स्प्राइट मूल रूप से "अंधेरा" होता है। मैं बस सभी पिक्सल के माध्यम से लूप, और एक मूल्य < द्वारा गुणा करें 1. यह सब कुछ है।

चूंकि यह बहुत धीमा है ... क्या कैनवास कार्यक्षमता, (कंपोजिटिंग, अस्पष्टता, जो कुछ भी) का उपयोग करके, एक ही चीज़ को करने के लिए एक बेहतर तरीका है, बिना किसी पिक्सल के लूपिंग के?

नोट: इस परत में कुछ 100% पारदर्शी पिक्सल हैं, और कुछ 100% अपारदर्शी पिक्सल हैं। दोनों को 100% अपारदर्शी या 100% पारदर्शी रहने की आवश्यकता है।

चीजें मुझे लगता है कि के बारे में सोचा गया है काम नहीं होगा:
1), एक नया कैनवास में स्प्राइट चित्रकारी कम अस्पष्टता के साथ। यह काम नहीं करेगा क्योंकि मुझे अपारदर्शी रहने के लिए sprites की जरूरत है, बस गहरा।
2) sprites चित्रकारी, और उनके ऊपर एक अर्द्ध पारदर्शी काले rect चित्रकारी। यह उन्हें गहरा कर देगा, लेकिन यह मेरे पारदर्शी पिक्सल को पारदर्शी नहीं बनाएगा ...

कोई विचार?

इस कोड मैं का उपयोग कर रहा है, अगर आप इसे में कुछ बहुत मूर्खतापूर्ण देखें:

function DarkenCanvas(baseImage, ratio) { 
    var tmpCanvas = document.createElement("canvas"); 
    tmpCanvas.width = baseImage.width; 
    tmpCanvas.height = baseImage.height; 
    var ctx = tmpCanvas.getContext("2d"); 
    ctx.drawImage(baseImage, 0, 0); 

    var pixelData = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height); 
    var length = pixelData.data.length; 
    for (var i = 0; i < length; i+= 4) { 
     pixelData.data[i] = pixelData.data[i] * ratio; 
     pixelData.data[i + 1] = pixelData.data[i + 1] * ratio; 
     pixelData.data[i + 2] = pixelData.data[i + 2] * ratio; 
    } 

    ctx.putImageData(pixelData, 0, 0); 
    return tmpCanvas 
} 

संपादित करें: यह क्या मैं छवि के साथ क्या करने की कोशिश कर रहा हूँ का एक उदाहरण है :
मूल: http://www.crystalgears.com/isoengine/sprites-ground.png
अन्धेरा: http://www.crystalgears.com/isoengine/sprites-ground_darkened.png

धन्यवाद!
डैनियल

+0

कृपया हमें जिस प्रभाव को प्राप्त करने का प्रयास कर रहे हैं उसकी तस्वीरों के पहले और बाद में हमें दिखाएं? –

+0

बस प्रश्न के नीचे दिए गए लिंक जोड़ा। धन्यवाद! –

+3

आप बस कुछ sprites अंधेरे करने की कोशिश कर रहे हैं? भलाई के लिए, इसके लिए प्रति पिक्सेल छवि डेटा का उपयोग न करें। अल्फा को संरक्षित करने के लिए बस अर्ध-पारदर्शी ब्लैक ओवरटॉप (एक अलग ['globalCompositeOperation'] (http://www.tutorialspoint.com/html5/canvas_composition.htm) के साथ बनाएं। – Phrogz

उत्तर

11

फ़ोगोज़ का सही विचार है। आप वास्तव में पूरी तरह से 'स्रोत-एटॉप' ग्लोबल कॉम्पोजिटऑपरेशन के साथ आधे पारदर्शी (या अनुपात-पारदर्शी) काले रंग को पेंट करना चाहते हैं।

इस तरह

: http://jsfiddle.net/F4cNg/

वास्तव में इस तरह परिष्कृत काला पर एक अच्छा सवाल था, लेकिन लेखक इसे नष्ट कर दिया है जो एक वास्तविक शर्म की बात है है। परिष्कृत आकार के साथ भी तैयार सामग्री पर काले-मास्क बनाना निश्चित रूप से संभव है।वे आपकी मदद नहीं कर सकता है, लेकिन पूर्णता के लिए के लिए और "काला कर कैनवास" सामान जहां कुछ भागों प्रकाश (अपवर्जन क्षेत्र) रखा जाता है के लिए खोज किसी को भी, कि 'XOR' globalCompositeOperation साथ किया जा सकता है, इस तरह के लिए:

http://jsfiddle.net/k6Xwy/1/

+0

आपको बहुत बहुत धन्यवाद, यह वही है जो मुझे चाहिए था। मैंने ड्राइंग के अंतिम परिणाम को अंधेरा माना। एक्सओआर चाल बहुत अच्छी है, उससे कहीं अधिक सरल मैं करने की योजना बना रहा था, लेकिन इसके बिना भी मैं सिर्फ "छेद" के साथ एक रेक्ट पेंट कर सकता था। उस समय, मुझे अब मेरे पारदर्शी पिक्सेल की परवाह नहीं है। मैं उस दृष्टिकोण को नहीं ले रहा हूं, हालांकि, क्योंकि मैं एक आईएसओ परिप्रेक्ष्य का उपयोग कर रहा हूं, और मेरी विधि, धीमी गति से, मुझे कुछ चीजों पर थोड़ा और सटीकता मिलती है जिनकी मुझे परवाह है। टिप के लिए धन्यवाद, हालांकि, मैं निश्चित रूप से कुछ समय में काम में आ जाएगा। धन्यवाद!!! –

10

आप इस प्रदर्शन टिप ?: http://ajaxian.com/archives/canvas-image-data-optimization-tip

वे डोम के लिए कॉल को कम करने के प्रदर्शन को बढ़ाने के बारे में बात को देखा है।

तो, यह टिप के आधार पर आप कोशिश कर सकते हैं:

var pixel = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height); 
    pixelData=pixel.data; // detach the pixel array from DOM 
    var length = pixelData.length; 
    for (var i = 0; i < length; i+= 4) { 
     pixelData[i] = pixelData[i] * ratio; 
     pixelData[i + 1] = pixelData[i + 1] * ratio; 
     pixelData[i + 2] = pixelData[i + 2] * ratio; 
    } 

आपका .data कॉल आप धीमा हो सकता है।

संबंधित मुद्दे