2014-07-14 7 views
8

को उसी पिक्सेल आकार के साथ दो कैनवास दिए गए, जहां कैनवास 1 में मनमानी छवि (jpg, png या ऐसे) शामिल हैं और कैनवास 2 में काले और गैर-काले पिक्सेल शामिल हैं।कैनवास छवि और कैनवास अल्फा मास्क डार्टौर उत्पन्न पीएनजी

मैं क्या हासिल करना चाहते हैं: एक तिहाई canvas3 मैं canvas1 क्लोन और हर काला canvas2 पिक्सेल (कालापन की एक सीमा सहित सकता है) के लिए canvas3 में पारदर्शी होना चाहते का उपयोग कर

मैं पहले से ही इस तरह एक काम समाधान है:

canvas3context.drawImage(canvas1,0,0); 
var c3img = canvas3context.getImageData(0,0,canvas3.width,canvas3.height); 
var c2img = canvas2context.getImageData(0,0,canvas2.width,canvas2.height); 
loop(){ 
    if(c2img i-th,i+1-th,i+2-th pixel is lower than threshold) 
     set c3img.data[i]=c3img.data[i+1]=c3img.data[i+2]=c3img.data[i+3]=0 
} 

ऊपर (छद्म) कोड के साथ समस्या यह है कि यह धीमी है, है तो मेरे सवाल यह है: किसी को भी यह कैसे ऊपर काफी तेज करने के लिए एक विचार साझा कर सकते हैं? मैं WebGL के बारे में सोचा था, लेकिन मैं इसके साथ काम नहीं - तो मैं shaders या उपकरण या शर्तों इस के लिए आवश्यक के बारे में पता नहीं है। एक और विचार था कि शायद मैं करने के लिए canvas2 परिवर्तित कर सकते हैं काले & सफेद किसी भी तरह बहुत तेजी से (न केवल ऊपर की तरह एक पाश में प्रत्येक पिक्सेल modifieng) और मिश्रण मोड के साथ काम पारदर्शी पिक्सेल

किसी भी मदद अत्यधिक सराहना की उत्पन्न करने के लिए

+0

पुनरावृत्त पिक्सल के साथ एक और समस्या यह है कि कैनवास छवि डेटा पढ़ने से क्रॉस-मूल समस्या में चल सकता है। –

उत्तर

7

अपने ही सवाल का जवाब, मैं एक काले रंग की & सफेद छवि के साथ एक मनमाना छवि विलय के लिए एक समाधान प्रदान करते हैं। जो भी अभी भी गायब है, वह कैनवास के केवल एक रंग के लिए अल्फा चैनल को सेट करना है।

मैं प्रश्नों को टुकड़ों में अलग करता हूं और उन्हें प्रत्येक का उत्तर देता हूं।

प्रश्न 1: कैसे हर पिक्सेल-बार दोहराना बिना ग्रेस्केल में एक कैनवास कन्वर्ट करने के लिए?

उत्तर: मिश्रण मोड 'चमक'

function convertCanvasToGrayscale(canvas){ 
    var tmp = document.createElement('canvas'); 
    tmp.width = canvas.width; 
    tmp.height = canvas.height; 
    var tmpctx = tmp.getContext('2d'); 

    // conversion 
    tmpctx.globalCompositeOperation="source-over"; // default composite value 
    tmpctx.fillStyle="#FFFFFF"; 
    tmpctx.fillRect(0,0,canvas.width,canvas.height); 
    tmpctx.globalCompositeOperation="luminosity"; 
    tmpctx.drawImage(canvas,0,0); 

    // write converted back to canvas 
    ctx = canvas.getContext('2d'); 
    ctx.globalCompositeOperation="source-over"; 
    ctx.drawImage(tmp, 0, 0); 
} 

प्रश्न 2 के साथ एक सफेद कैनवास पर छवि आकर्षित: कैसे पुनरावृत्ति के बिना काले & सफेद में ग्रेस्केल कैनवास कन्वर्ट करने के लिए हर पिक्सेल?

उत्तर: रंग #FEFEFE साथ दो बार रंग-चकमा मिश्रण मोड काम करेगा

function convertGrayscaleCanvasToBlackNWhite(canvas){ 
    var ctx = canvas.getContext('2d'); 

    // in case the grayscale conversion is to bulky for ya 
    // darken the canvas bevore further black'nwhite conversion 
    //for(var i=0;i<3;i++){ 
    // ctx.globalCompositeOperation = 'multiply'; 
    // ctx.drawImage(canvas, 0, 0); 
    //} 

    ctx.globalCompositeOperation = 'color-dodge'; 
    ctx.fillStyle = "rgba(253, 253, 253, 1)"; 
    ctx.beginPath(); 
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
    ctx.fill(); 
    ctx.globalCompositeOperation = 'color-dodge'; 
    ctx.fillStyle = "rgba(253, 253, 253, 1)"; 
    ctx.beginPath(); 
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
    ctx.fill(); 
} 

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

प्रश्न 3 के बाकी क्या करेंगे काला पिक्सेल का उपयोग करते हुए रंग-चकमा की मात्रा में वृद्धि: कैसे हर पिक्सेल-बार दोहराना के बिना किसी अन्य कैनवास के साथ एक काले & व्हाइट कैनवास विलय करने के लिए?

उत्तर: उपयोग 'गुणा' मिश्रण मोड

function getBlendedImageWithBlackNWhite(canvasimage, canvasbw){ 
    var tmp = document.createElement('canvas'); 
    tmp.width = canvasimage.width; 
    tmp.height = canvasimage.height; 

    var tmpctx = tmp.getContext('2d'); 

    tmpctx.globalCompositeOperation = 'source-over'; 
    tmpctx.drawImage(canvasimage, 0, 0); 

    // multiply means, that every white pixel gets replaced by canvasimage pixel 
    // and every black pixel will be left black 
    tmpctx.globalCompositeOperation = 'multiply'; 
    tmpctx.drawImage(canvasbw, 0, 0); 

    return tmp; 
} 

प्रश्न 4: हर पिक्सेल-बार दोहराना के बिना एक काले & व्हाइट कैनवास को उलटने कैसे?

उत्तर: उपयोग 'अंतर' मिश्रण मोड

function invertCanvas(canvas){ 
    var ctx = canvas.getContext("2d"); 

    ctx.globalCompositeOperation = 'difference'; 
    ctx.fillStyle = "rgba(255, 255, 255, 1)"; 
    ctx.beginPath(); 
    ctx.fillRect(0, 0, canvas.width, canvas.height); 
    ctx.fill(); 
} 
अब 'मर्ज' एक canvasmask के साथ एक canvasimage को

एक प्रदर्शन के बारे में

convertCanvasToGrayscale(canvasmask); 
convertGrayscaleCanvasToBlackNWhite(canvasmask); 
result = getBlendedImageWithBlackNWhite(canvasimage, canvasmask); 

कर सकते हैं: स्पष्ट रूप से उन लोगों के मिश्रण मोड प्रत्येक पिक्सेल को संशोधित करने से थोड़ा तेज़ होते हैं और थोड़ा तेज पाने के लिए एक फ़ंक्शन में आवश्यकतानुसार सभी कार्यों को एक साथ पैक कर सकते हैं और केवल एक tmpcanvas रीसायकल कर सकते हैं - लेकिन यह आर को छोड़ दिया जाता है eader ^^

एक sidenote के रूप में: मैं परीक्षण किया है कि कैसे जिसके परिणामस्वरूप png का आकार अलग है जब आप तुलना ऊपर एक ही छवि के साथ getBlendedImageWithBlackNWhite परिणाम है, लेकिन काले क्षेत्रों प्रत्येक पिक्सेल अल्फ़ा चैनल पुनरावृत्ति और निर्धारित करके पारदर्शी बना रहे हैं अंतर आकार में लगभग कुछ भी नहीं है और इस प्रकार यदि आपको वास्तव में अल्फा-मास्क की आवश्यकता नहीं है, तो यह जानकारी कि प्रत्येक ब्लैक पिक्सेल पारदर्शी होने के लिए पर्याप्त हो सकती है, भविष्य के लिए

नोट: कोई भी काले और सफेद के अर्थ को उलटा कर सकता है invertCanvas() फ़ंक्शन

यदि आप और जानना चाहते हैं कि मैं उन मिश्रण मोड का उपयोग क्यों करता हूं या कैसे मिश्रण मो des वास्तव में काम करते हैं आप उन्हें पीछे गणित की जांच होनी चाहिए - imho आप इस तरह के कार्यों विकसित करने में सक्षम है, तो फिर न जानते हैं कि कैसे वे वास्तव में काम नहीं कर रहे हैं: math behind blend modes canvas composition standard including a bit math

एक उदाहरण की जरूरत है - अंतर स्पॉट: http://jsfiddle.net/C3fp4/1/

+0

ग्रेट सामान। ध्यान दें कि इनमें से कुछ ग्लोबल कॉम्पोजिटऑपरेशन फिल्टर अभी तक सफारी में काम नहीं करते हैं। – Mulhoon

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