2015-08-22 9 views
7

मेरे पास canvas है जो png छवि के साथ लोड किया गया है। मैं इस तरह .toDataURL() विधि द्वारा अपने jpg base64 स्ट्रिंग मिलती है:पीएनजी छवि से जेपीजी छवि बनाते समय एचटीएमएल कैनवास काले पृष्ठभूमि को बदलें

$('#base64str').val(canvas.toDataURL("image/jpeg")); 

लेकिन png छवि के पारदर्शी हिस्सों नई jpg छवि में काले दिखाए जाते हैं।

इस रंग को सफेद में बदलने के लिए कोई समाधान? अग्रिम में धन्यवाद।

उत्तर

6

यह ब्लैकिंग होता है क्योंकि 'छवि/जेपीईजी' रूपांतरण में सभी कैनवास पिक्सेल के अल्फा को पूरी तरह से अपारदर्शी (अल्फा = 255) में सेट करना शामिल है। समस्या यह है कि पारदर्शी कैनवास पिक्सेल रंग fully-black-but-transparent हैं। तो जब आप इन काले पिक्सेल अपारदर्शी को चालू करते हैं, तो परिणाम एक काला जेपीईजी होता है।

वर्कअराउंड सभी गैर-अपारदर्शी कैनवास पिक्सल को काले रंग की बजाय आपके वांछित सफेद रंग में मैन्युअल रूप से बदलना है।

इस तरह जब उन्हें अपारदर्शी बनाया जाता है तो वे काले पिक्सेल के बजाय सफेद दिखाई देंगे।

// change non-opaque pixels to white 
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
var data=imgData.data; 
for(var i=0;i<data.length;i+=4){ 
    if(data[i+3]<255){ 
     data[i]=255; 
     data[i+1]=255; 
     data[i+2]=255; 
     data[i+3]=255; 
    } 
} 
ctx.putImageData(imgData,0,0); 
+0

धन्यवाद। क्या मैं इसे एएसपी.NET कोड में कर सकता हूं, जिसके बाद काले-गद्देदार छवि को कोड पर पास कर दिया गया है? –

+0

आपका स्वागत है! कोड-बैक को पास करने से पहले आपको क्लाइंट-साइड पर छवि को संसाधित करना चाहिए। ऐसा इसलिए है क्योंकि एचटीएमएल 5 कैनवास केवल जावास्क्रिप्ट के साथ काम करता है और जेएस कोड-बैक में मूल रूप से उपलब्ध नहीं है (कम से कम एचटीएमएल 5 कैनवास का उपयोग करने के तरीकों में उपलब्ध नहीं है)। – markE

+0

मुझे विश्वास नहीं है कि यह संबोधित करने का यही एकमात्र तरीका है। डिफ़ॉल्ट रंग बदलने के लिए कुछ रास्ता होना चाहिए। मुझे इसका शोध करना होगा। – Laereom

2

मार्क्स जवाब सही है, लेकिन जब एक तस्वीर कुछ लागू किया एंटीलायज़िंग़ है, निर्यात छवि के रूप में (मुख्य रूप से पाठ) होना चाहिए के रूप में अच्छा नहीं होगा:

यहाँ कैसे। मैं उसके समाधान को बढ़ाने के लिए करना चाहते हैं:

// change non-opaque pixels to white 
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
var data=imgData.data; 
for(var i=0;i<data.length;i+=4){ 
    if(data[i+3]<255){ 
     data[i] = 255 - data[i]; 
     data[i+1] = 255 - data[i+1]; 
     data[i+2] = 255 - data[i+2]; 
     data[i+3] = 255 - data[i+3]; 
    } 
} 
ctx.putImageData(imgData,0,0); 
0
// change non-opaque pixels to white 
var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
var data=imgData.data; 
for(var i=0;i<data.length;i+=4){ 
    if(data[i+3]<255){ 
     data[i] = 255 - data[i]; 
     data[i+1] = 255 - data[i+1]; 
     data[i+2] = 255 - data[i+2]; 
     data[i+3] = 255 - data[i+3]; 
    } 
+0

मेरा सुझाव है कि आप इस बारे में एक स्पष्टीकरण जोड़ें कि यह समस्या को कैसे हल करता है – Obromios

0

तुम सिर्फ (डेटा [i + 3] == 0) के लिए जाँच सफेद केवल पूर्ण पारदर्शी पिक्सेल के लिए ले जाना चाहते हैं के बजाय (डेटा [i + 3] < 255)।

5

यह उत्तर थोड़ा लंबा है, लेकिन मुझे लगता है कि यह अधिक 'सही' है कि यह कच्चे कैनवास डेटा को सीधे संशोधित किए बिना इन चीजों को संभालता है। मुझे लगता है कि एक सुंदर गन्दा और सैद्धांतिक रूप से असंतुष्ट समाधान होना है। इसे प्राप्त करने के लिए कार्यों में बनाया गया है, और इनका उपयोग किया जाना चाहिए।

function canvasToImage(backgroundColor){ 

var context = document.getElementById('canvas').getContext('2d'); 

canvas = context.canvas; 
//cache height and width   
var w = canvas.width; 
var h = canvas.height; 

var data; 

//get the current ImageData for the canvas. 
data = context.getImageData(0, 0, w, h); 

//store the current globalCompositeOperation 
var compositeOperation = context.globalCompositeOperation; 

//set to draw behind current content 
context.globalCompositeOperation = "destination-over"; 

//set background color 
context.fillStyle = backgroundColor; 

//draw background/rect on entire canvas 
context.fillRect(0,0,w,h); 

//get the image data from the canvas 
var imageData = this.canvas.toDataURL("image/jpeg"); 

//clear the canvas 
context.clearRect (0,0,w,h); 

//restore it with original/cached ImageData 
context.putImageData(data, 0,0); 

//reset the globalCompositeOperation to what it was 
context.globalCompositeOperation = compositeOperation; 

//return the Base64 encoded data url string 
return imageData; 
} 

मूल रूप से, आप एक सफेद पृष्ठभूमि छवि बनाने और कैनवास के तहत यह बुनियाद और फिर उस प्रिंट: यहाँ समाधान मैंने पाया/चोरी होती है। यह फ़ंक्शन ज्यादातर किसी के ब्लॉग से चोरी किया जाता है, लेकिन इसे थोड़ा बदलाव की आवश्यकता होती है - जैसे वास्तव में संदर्भ प्राप्त करना - और सीधे मेरे (काम करने वाले) कोड से कॉपी किया जाता है, ताकि जब तक आपके कैनवास तत्व में आईडी 'कैनवास' हो, आप इसे कॉपी/पेस्ट करने और इसे काम करने में सक्षम होना चाहिए।

इस ब्लॉग पोस्ट मैं से इसे संशोधित है:

http://www.mikechambers.com/blog/2011/01/31/setting-the-background-color-when-generating-images-from-canvas-todataurl/

मेरी समारोह का बड़ा लाभ पर इस जो अधिक क्रोम में अच्छी तरह से काम करने की संभावना है कि यह png के बजाय से jpeg आउटपुट है, , जिसमें 2 एमबी की डेटोरल सीमा है, और यह वास्तव में संदर्भ को पकड़ लेती है, जो मूल कार्य में एक चमकदार चूक थी।

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