解决canvas转base64/jpeg时透明区域变成黑色背景的方法
最近在工作遇到一个问题,在将png图片转jpeg时,透明区域被填充成黑色,通过网上的介绍找到了解决的方法,现在总结下分享给同样遇到这个问题的朋友们,感兴趣的可以通过本文详细学习下。
在用canvas将png图片转jpeg时,发现透明区域被填充成黑色。
代码如下:
- <p>Canvas:</p>
- <canvas id="canvas" style="border: 1px solid #ccc;"></canvas>
- <br>
- <p>Base64转码后的图片:</p>
- <div id="base64Img"></div>
- <script type="text/javascript">
- var base64Img = document.getElementById("base64Img"),
- canvas = document.getElementById("canvas"),
- context = canvas.getContext("2d");
- // 创建新图片
- var img = new Image();
- img.src = "1.png";
- img.addEventListener("load", function() {
- // 绘制图片到canvas上
- canvas.width = img.width;
- canvas.height = img.height;
- context.drawImage(img, 0, 0);
- getBase64(canvas, function(dataUrl) {
- // 展示base64位的图片
- var newImg = document.createElement("img");
- newImg.src = dataUrl;
- base64Img.appendChild(newImg);
- });
- }, false);
- // 获取canvas的base64图片的dataURL(图片格式为image/jpeg)
- function getBase64(canvas, callback) {
- var dataURL = canvas.toDataURL("image/jpeg");
- if(typeof callback !== undefined) {
- callback(dataURL);
- }
- }
- </script>
效果如下:
为什么canvas会png的透明区域转成黑色呢?
canvas转换成jpeg之前移除alpha通道,所以透明区域被填充成了黑色。
但是,我们希望的是,canvas可以将png的透明区域填充成白色。
那么怎么将canvas中的透明区域填充成白色呢?
以下是我实践过的两种解决方案,希望对你有帮助。
解决方案一:将透明的pixel设成白色
因为png图片的背景都是透明的,所以我们可以寻找透明的pixel,然后将其全部设置成白色,核心代码如下:
- // 将canvas的透明背景设置成白色
- var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
- for(var i = 0; i < imageData.data.length; i += 4) {
- // 当该像素是透明的,则设置成白色
- 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转码后的图片:</p>
- <div id="base64Img"></div>
- <script type="text/javascript">
- var base64Img = document.getElementById("base64Img"),
- canvas = document.getElementById("canvas"),
- context = canvas.getContext("2d");
- // 创建新图片
- var img = new Image();
- img.src = "1.png";
- img.addEventListener("load", function() {
- // 绘制图片到canvas上
- canvas.width = img.width;
- canvas.height = img.height;
- context.drawImage(img, 0, 0);
- // 将canvas的透明背景设置成白色
- var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
- for(var i = 0; i < imageData.data.length; i += 4) {
- // 当该像素是透明的,则设置成白色
- 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);
- // 展示base64位的图片
- getBase64(canvas, function(dataUrl) {
- var newImg = document.createElement("img");
- newImg.src = dataUrl;
- base64Img.appendChild(newImg);
- });
- }, false);
- // 获取canvas的base64图片的dataURL(图片格式为image/jpeg)
- function getBase64(canvas, callback) {
- var dataURL = canvas.toDataURL("image/jpeg");
- if(typeof callback !== undefined) {
- callback(dataURL);
- }
- }
- </script>
效果如下:
缺点显而易见。当png图片上存在半透明区域时,会将其填充为黑色。这是我们不希望的。
解决方案二:在canvas绘制前填充白色背景
核心代码如下:
- // 在canvas绘制前填充白色背景
- context.fillStyle = "#fff";
- context.fillRect(0, 0, canvas.width, canvas.height);
完整代码如下:
- <p>Canvas:</p>
- <canvas id="canvas" style="border: 1px solid #ccc;"></canvas>
- <br>
- <p>Base64转码后的图片:</p>
- <div id="base64Img"></div>
- <script type="text/javascript">
- var base64Img = document.getElementById("base64Img"),
- canvas = document.getElementById("canvas"),
- context = canvas.getContext("2d");
- // 创建新图片
- var img = new Image();
- img.src = "1.png";
- img.addEventListener("load", function() {
- // 绘制图片到canvas上
- canvas.width = img.width;
- canvas.height = img.height;
- // 在canvas绘制前填充白色背景
- context.fillStyle = "#fff";
- context.fillRect(0, 0, canvas.width, canvas.height);
- context.drawImage(img, 0, 0);
- // 展示base64位的图片
- getBase64(canvas, function(dataUrl) {
- var newImg = document.createElement("img");
- newImg.src = dataUrl;
- base64Img.appendChild(newImg);
- });
- }, false);
- // 获取canvas的base64图片的dataURL(图片格式为image/jpeg)
- function getBase64(canvas, callback) {
- var dataURL = canvas.toDataURL("image/jpeg");
- if(typeof callback !== undefined) {
- callback(dataURL);
- }
- }
- </script>
效果如下:
Perfect!
显然,在canvas绘制前填充白色背景这种方法,不仅简单,而且对png图片的半透明区域填充难看的黑色块。推荐这种解决方案。
另:canvas.toDataURL()方法不允许处理跨域图片。否则会报错。
转载地址:http://www.jb51.net/html5/503985.html
解决canvas转base64/jpeg时透明区域变成黑色背景的方法的更多相关文章
- 一键切换皮肤的解决思想及iframe嵌套时寻找下级iframe的方法
项目中有个一键切换皮肤的功能,感觉还不错,记录下,就是各颜色样式设置起来太复杂了,不知道有没有更简便的方法: 1.切换皮肤结构层 <li title="<s:text name= ...
- 解决pycharm运行py文件时只有unittest选项的方法
有时候在编完脚本开始运行时,发现某个py脚本右键运行的选项不是run,二是run in unittest,试过很多方法都不能很好的去除,主要是因为脚本中含有test字符串,一种解决方法是将脚本中所有的 ...
- 解决 canvas 将图片转为base64报错: Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasEleme...
问题描述 当用户点击分享按钮时,生成一张海报,可以保存图片分享到朋友圈,用户的图片是存储在阿里云的OSS,当海报完成后,执行.canvas.toDataURL("image/png" ...
- 解决 canvas 绘图在高清屏中的模糊问题
解决 canvas 绘图在高清屏中的模糊问题 为什么模糊 CSS 像素是一个抽象单位(1 px),浏览器根据某种规则将 css 像素转化为屏幕需要的实际像素值. 在高清屏之前,屏幕上显示一个像素点需要 ...
- 小程序canvas转base64方法 使用upng库 亲测没问题
普通字符串base64编码转化可以使用原生的atob和btoa方法 图片转码:传统的图片转base64的方法可以采用FileReader的readAsDataURL()或canvas.toDataUR ...
- 基于vue上传base64图片,通过canvas压缩base64
其实和vue关系不大,和我们之前做上传压缩性质是一样的 当然下面的代码是没有处理ios横屏拍照的bug的 有兴趣的可以多搜一下 网上都有相应的解答 .. var that = this if (e. ...
- 解决SQLSERVER在还原数据时出现的“FILESTREAM功能被禁用”问题
解决SQLSERVER在还原数据时出现的“FILESTREAM功能被禁用”问题 今天由于测试需要,在网上下载了Adventureworks2008实例数据库的BAK文件,进行还原时出现了这样的错误“F ...
- 解决iphone填写表单时,表单项获取焦点时往下拉屏,导致顶部标题栏下滑错位
$(function () { //解决iphone填写表单时,表单项获取焦点时往下拉屏,导致顶部标题栏下滑错位 var u = navigator.userAgent; var isiOS = !! ...
- 图片_ _Android有效解决加载大图片时内存溢出的问题 2
Android有效解决加载大图片时内存溢出的问题 博客分类: Android Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或 setImageResource或 Bit ...
随机推荐
- arcgis制作风或水流速流向图
制作风或水流速流向图 风速风向图或流速流向图相信大家都已经见过不少,但不知道有多少人会制作这样炫的专题图,下面这边文章向我们展示了当基本数据U和V矢量被存储时,怎样计算风或水流的速度和方向和对其进行符 ...
- Foundation ----->NSSet
1.集合类 NSString *s1 = @"zhangsan"; NSString *s2 = @"lisi"; NSString * ...
- HTML中图片添加
图片添加后保存的是添加路径 例: <div class="form-group"> <label class="col-sm-3 control-lab ...
- JavaScript小知识
1.<script>标签的出现使整个页面因脚本解析.运行而出现等待: 2.合并脚本,每个 HTTP请求都会产生额外的性能负担,下载一 个 100KB 的文件比下载四个 25KB的文件要快: ...
- window7下karma 报 nodejs request TypeError: The header content contains invalid characters BUG
这个BUG 估计只有中国人才 遇到 打开你的依赖node_modules\karma\node_modules\connect\lib\patch.js 将里面的setHeader方法改成下面这样,干 ...
- mssql2000 身份证号码验证
CREATE VIEW thisDate --返回当前日期,因为自定义函数中不能使用GETDATE() AS ),) AS aDate )) /*mssql2000 返回值=0,身份证校验正确 1:位 ...
- DOM元素querySelectorAll可能让你意外的特性表现
一.时间紧急,废话少说 本文所在的页面藏匿了下面这些代码: <img id="outside"> <div id="my-id"> &l ...
- 有关Select option 元素
动态添加option元素以及option元素被选中方法: function getType() { ); shadowCoverTipAdd("加载中,请稍候.."); $.aja ...
- cdnbest的站点设置里设置url跳转设置
示例: 内容示例写法: ^http://kangleweb.com/(.*)$ https://www.kangleweb.com/$1 这只是一个例子,其他用法您可以自已多试试
- 抢凳子日数据sql
--先找到档期select * from hv_item_info a where a.report_begdate > '2016-07-28' and a.report_begdate &l ...