When you use canvas to turn a PNG picture to JPEG, the transparent area is found to be filled with black.
The code is as follows:
<p>Canvas:</p>
<canvas id= "Canvas" style= "border:1px solid #ccc;" ></canvas>
<br>
<p>base64 the picture after transcoding:</p>
<div id= "Base64img" ></div>
<script type= "Text/javascript" >
var base64img = document.getElementById ("base64img"),
Canvas = document.getElementById ("Canvas"),
Context = Canvas.getcontext ("2d");
Create a new picture
var img = new Image ();
IMG.SRC = "1.png";
Img.addeventlistener ("Load", function () {
Draw pictures to Canvas
Canvas.width = Img.width;
Canvas.height = Img.height;
Context.drawimage (IMG, 0, 0);
GetBase64 (canvas, function (Dataurl) {
Picture showing base64 bit
var newimg = document.createelement ("img");
NEWIMG.SRC = Dataurl;
Base64img.appendchild (NEWIMG);
});
}, False);
Gets the dataurl of the Base64 picture for canvas (picture format is image/jpeg)
function GetBase64 (canvas, callback) {
var dataurl = Canvas.todataurl ("Image/jpeg");
if (typeof callback!== undefined) {
Callback (Dataurl);
}
}
</script>
Why would canvas PNG's transparent area turn black?
Canvas removes the alpha channel before converting to JPEG, so the transparent area is populated with black.
What we want, however, is that canvas can fill the transparent area of PNG with white.
So how do you fill the transparent area of the canvas into white?
Here are two solutions I have practiced, and I hope it will help you.
Solution One: Set the transparent pixel to white
Because the background of the PNG picture is transparent, we can look for the transparent pixel, then set it all to white, the core code is as follows:
Set the transparent background of the canvas to white
var imagedata = context.getimagedata (0, 0, canvas.width, canvas.height);
for (var i = 0; i < imageData.data.length i + + 4) {
When the pixel is transparent, it is set to white
if (Imagedata.data[i + 3] = = 0) {
Imagedata.data[i] = 255;
Imagedata.data[i + 1] = 255;
Imagedata.data[i + 2] = 255;
Imagedata.data[i + 3] = 255;
}
}
Context.putimagedata (imagedata, 0, 0);
<p>Canvas:</p>
<canvas id= "Canvas" style= "border:1px solid #ccc;" ></canvas>
<br>
<p>base64 the picture after transcoding:</p>
<div id= "Base64img" ></div>
<script type= "Text/javascript" >
var base64img = document.getElementById ("base64img"),
Canvas = document.getElementById ("Canvas"),
Context = Canvas.getcontext ("2d");
Create a new picture
var img = new Image ();
IMG.SRC = "1.png";
Img.addeventlistener ("Load", function () {
Draw pictures to Canvas
Canvas.width = Img.width;
Canvas.height = Img.height;
Context.drawimage (IMG, 0, 0);
Set the transparent background of the canvas to white
var imagedata = context.getimagedata (0, 0, canvas.width, canvas.height);
for (var i = 0; i < imageData.data.length i + + 4) {
When the pixel is transparent, it is set to white
if (Imagedata.data[i + 3] = = 0) {
Imagedata.data[i] = 255;
Imagedata.data[i + 1] = 255;
Imagedata.data[i + 2] = 255;
Imagedata.data[i + 3] = 255;
}
}
Context.putimagedata (imagedata, 0, 0);
Picture showing base64 bit
GetBase64 (canvas, function (Dataurl) {
var newimg = document.createelement ("img");
NEWIMG.SRC = Dataurl;
Base64img.appendchild (NEWIMG);
});
}, False);
Gets the dataurl of the Base64 picture for canvas (picture format is image/jpeg)
function GetBase64 (canvas, callback) {
var dataurl = Canvas.todataurl ("Image/jpeg");
if (typeof callback!== undefined) {
Callback (Dataurl);
}
}
</script>
Shortcomings are obvious. When a semitransparent region is present on a PNG picture, it is populated with black. That's what we don't want.
Solution Two: Fill the white background before canvas drawing
The core code is as follows:
Fill a white background before canvas drawing
Context.fillstyle = "#fff";
Context.fillrect (0, 0, canvas.width, canvas.height);
The complete code is as follows:
<p>Canvas:</p>
<canvas id= "Canvas" style= "border:1px solid #ccc;" ></canvas>
<br>
<p>base64 the picture after transcoding:</p>
<div id= "Base64img" ></div>
<script type= "Text/javascript" >
var base64img = document.getElementById ("base64img"),
Canvas = document.getElementById ("Canvas"),
Context = Canvas.getcontext ("2d");
Create a new picture
var img = new Image ();
IMG.SRC = "1.png";
Img.addeventlistener ("Load", function () {
Draw pictures to Canvas
Canvas.width = Img.width;
Canvas.height = Img.height;
Fill a white background before canvas drawing
Context.fillstyle = "#fff";
Context.fillrect (0, 0, canvas.width, canvas.height);
Context.drawimage (IMG, 0, 0);
Picture showing base64 bit
GetBase64 (canvas, function (Dataurl) {
var newimg = document.createelement ("img");
NEWIMG.SRC = Dataurl;
Base64img.appendchild (NEWIMG);
});
}, False);
Gets the dataurl of the Base64 picture for canvas (picture format is image/jpeg)
function GetBase64 (canvas, callback) {
var dataurl = Canvas.todataurl ("Image/jpeg");
if (typeof callback!== undefined) {
Callback (Dataurl);
}
}
</script>
Obviously, filling the white background before canvas is not only simple, but also fills the translucent area of the PNG picture with unsightly black blocks. Recommend this solution.
Another: the Canvas.todataurl () method does not allow Cross-domain pictures to be processed. Otherwise it will be an error.