1.背景

之前做过一个营销类移动端h5项目-海报生成器,上传用户本地图片合成海报并支持下载,这次有时间了整理整理。

2.几个重点

上传本地图片并支持预览

处理ios照片翻转

使用canvas对图片等比拉伸缩放并居中裁剪

使用canvas绘制图片以及文本

输出base64并支持下载

3.上传图片

废话不多说,使用html的 标签可以支持文件上传,前端上传验证的话,设置accept="image/*"将文件类型限制为图像。

复制代码

获取当前上传的图片。

var file = event.target.files[0];

复制代码

要完成本地预览图片,需要使用FileReader对象读取所要处理的文件数据,使用readAsDataURL将文件以Data URL形式进行读入页面。同时为了处理ios下照片翻转角的问题,需要先对翻转的照片进行一个修正。使用exif-js这个库可以获取照片的信息,获得翻转角,然后使用canvas画布对图片进行翻转矫正。

//上传图片

uploadImg = event => {

var that = this;

var file = event.target.files[0];

if (!file) {

return;

}

var orientation = "";

//EXIF js 可以读取图片的元信息 https://github.com/exif-js/exif-js

EXIF.getData(file, function () {

orientation = EXIF.getTag(this, 'Orientation');

});

var reader = new FileReader();

// 将文件以Data URL形式进行读入页面

reader.readAsDataURL(file);

reader.onload = function () {

var sourceImg = new Image();

sourceImg.onload = function () {

var imgRadio=sourceImg.width/sourceImg.height;

var imgStyle={

'width':imgRadio>1?'100%':'auto',

'height':imgRadio<1?'100%':'auto'

}

that.setState({isUploaded: true, sourceImg: sourceImg, hasFile: true,previewImgStyle:imgStyle})

};

//处理iOS照片旋转

(async function (context) {

sourceImg.src = orientation && orientation != "1"

? await that.rotateImage(context.result, orientation)

: context.result;

})(this);

};

}

//处理ios照片翻转

rotateImage = (img, dir) => {

return new Promise((resolve, reject) => {

var image = new Image();

var that = this;

image.onload = function () {

var degree = 0,

drawWidth=this.naturalWidth,

drawHeight=this.naturalHeight,

width,

height;

var canvas = document.createElement('canvas');

canvas.width = width = drawWidth;

canvas.height = height = drawHeight;

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

//判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式

switch (dir) {

//iphone横屏拍摄,此时home键在左侧

case 3:

degree = 180;

drawWidth = -width;

drawHeight = -height;

break;

//iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)

case 6:

canvas.width = height;

canvas.height = width;

degree = 90;

drawWidth = width;

drawHeight = -height;

break;

//iphone竖屏拍摄,此时home键在上方

case 8:

canvas.width = height;

canvas.height = width;

degree = 270;

drawWidth = -width;

drawHeight = height;

break;

}

//使用canvas旋转校正

context.rotate(degree * Math.PI / 180);

context.drawImage(this, 0, 0, drawWidth, drawHeight);

//返回校正图片

resolve(canvas.toDataURL("image/jpeg", 1));

}

image.src = img;

});

}

复制代码

html

复制代码

效果:

4.裁剪图片

到此完成了图片的上传和预览,接下来处理海报合成,背景图是640*1136大小的,但是上传的图片可以是五花八门的,有可能是方的,也有可能是非常长的- -,需要保证图片不变形并显示中心部分,因此需要比较照片的宽高比与背景的宽高比,并拉伸压缩至宽度或高度与背景图片相同,然后裁剪中间部分。

var canvas = document.createElement('canvas');

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

canvas.width = 640;

canvas.height = 1136;

//处理等比拉伸压缩用户图片并居中裁剪

var imgRatio = canvas.width / canvas.height; //目标图片的宽高比

var userimgRatio = that.state.sourceImg.width / that.state.sourceImg.height; //原始图片的宽高比

var r = (userimgRatio > imgRatio)

? (canvas.height / that.state.sourceImg.height)

: (canvas.width / that.state.sourceImg.width);

var drawObj = {

sx: userimgRatio > imgRatio

? (that.state.sourceImg.width - canvas.width / r) / 2

: 0,

sy: userimgRatio > imgRatio

? 0

: (that.state.sourceImg.height - canvas.height / r) / 2,

sWidth: canvas.width / r,

sHeight: canvas.height / r,

dx: 0,

dy: 0,

dWidth: canvas.width,

dHeight: canvas.height

};

//图片居中裁剪

ctx.drawImage(that.state.sourceImg, drawObj.sx, drawObj.sy, drawObj.sWidth, drawObj.sHeight, drawObj.dx, drawObj.dy, drawObj.dWidth, drawObj.dHeight);

复制代码

canvas的drawImage方法总共有9个参数

如图示,上传了一张尺寸小且为正方形的图片,先根据背景图片计算宽高比,在用户图片中裁剪出一个宽高比与背景图片宽高比一样的最大范围,并且裁剪图片中心部分,获得开始裁剪的点,左上角这个点x坐标为(that.state.sourceImg.width - canvas.width / r) / 2,y坐标为0,对应sx和sy参数,被剪切图像的宽高是中间部分的宽高(四个黄点所围),即参数中的swidth为canvas.width / r,sheight为canvas.height / r,最终图片放置位置为铺满canvas,即x=0,y=0,最终图片大小即为canvas的大小,会拉伸图片铺满canvas,最终实现了“获取用户图片中心部分并铺满背景的效果”

5.绘制图片

最后将背景图与上传的图片绘制在一起,并生成base64格式,可以长按保存。

var newimg = new Image();

newimg.src = "/src/images/bg.png";

newimg.onload = function () {

ctx.drawImage(newimg, 0, 0, canvas.width, canvas.height);

ctx.fillStyle = "#fff";

ctx.font = 36 + "px sans-serif";

ctx.fillText(that.state.slogan1, 50, 1000);

ctx.fillText(that.state.slogan2, 50, 1070);

that.setState({

resultImgUrl: canvas.toDataURL("image/jpeg", .5),

isGenerated: true

})

};

复制代码

HTML5海报生成器源码,原生js小项目 - canvas海报生成器相关推荐

  1. 别踩白块html源码,原生JS实现别踩白块小游戏(七)

    在前面的文章<原生JS实现别踩白块小游戏(六)>中,为大家介绍了实现别踩白块小游戏的js代码中移动效果的方法概述. 下面我们就继续结合源代码中js代码部分,为大家介绍具体的实现方法. 相关 ...

  2. react小项目 - canvas海报生成器

    1.背景   之前做过一个营销类移动端h5项目-海报生成器,上传用户本地图片合成海报并支持下载,这次有时间了整理整理. 2.几个重点 上传本地图片并支持预览 处理ios照片翻转 使用canvas对图片 ...

  3. 傻瓜一键制作html,营销号生成器源码(纯HTML+CSS+JS)

    营销号生成器源码(纯HTML+CSS+JS),最近很火的营销号生成器相信很多人都不陌生,它能帮您生成一段非常标准的小编文案,并且内容废话极多,一般用来调侃使用.本次带来营销号生成器源码资源下载,包含了 ...

  4. 小程序源码:朋友圈集赞万能截图生成器微信小程序源码下载

    大家好这是一款朋友圈积攒截图小程序 里面内涵三款样式生成,一款图文,一款分享,一款查看的样式 也就是我们微信朋友圈所用到的样式就包含了 里面的流量主 那些可以用户自由的添加哈! 赞的数量那些可以用户自 ...

  5. 微信发卡小程序源码-自动发卡小程序源码-带流量主功能

    简介: 此套源码带流量主功能裂变扩展,让你赚个广告收益. 朋友花300大洋互站买来的,源码没有动,而且测试搭建表现良好! 源码功能: 小程序系统/多种卡密领取模式/流量主: 支持:添加分类丨分类介绍丨 ...

  6. [含论文+源码等]微信小程序电影购票+后台管理系统源码

    IT源码 <微信小程序电影购票+后台管理系统>该项目含有源码.论文等资料.配套开发软件.软件安装教程.项目发布教程等 本系统包含微信小程序做的电影购票前台和Java做的后台管理系统: 微信 ...

  7. (微信小程序)微信小程序-毕设级项目搭建-微信阅读小程序(内含源码,微信小程序+java逻辑后台+vue管理系统)~不求完美,实现就好

    转载地址:(微信小程序)微信小程序-毕设级项目搭建-微信阅读小程序(内含源码,微信小程序+java逻辑后台+vue管理系统)~不求完美,实现就好 转载请注明出处 作者:Happy王子乐 个人网站(整理 ...

  8. 含论文+辩论PPT+源码等]微信小程序ssm社区心理健康服务平台+后台管理系统

    下载地址: https://download.csdn.net/download/m0_71595576/85519044?spm=1001.2014.3001.5503 项目介绍: 含论文+辩论PP ...

  9. [含论文+源码等]微信小程序居家养老+后台管理系统[包运行成功]

    下载地址:https://download.csdn.net/download/BSDKT/85347133 项目介绍: [含论文+源码等]微信小程序居家养老+后台管理系统[包运行成功] 系统说明: ...

  10. 微信小程序电商源码:外卖小程序,电商小程序,门店类小程序,展示类小程序,批发商城小程序、分销小程序。

    介绍: 1.naicha 2.xianhua 3.xingbake 4.zhubaoxiao 5.zhubaoxiao 6.majiangshangcheng 7.jiafang 8.huazhuan ...

最新文章

  1. 自己实现文本相似度算法(余弦定理)
  2. 实现ASP.NET MVC3 HtmlHelper 的 RadioButtonList 与CheckBoxList 扩展
  3. 大厂来的水货CTO:低级bug被敲诈50万美元,事后删代码隐藏证据,最后收到死亡威胁...
  4. python实现名片管理系统在哪里_python实现名片管理系统项目
  5. 二十万字C/C++、嵌入式软开面试题全集宝典六
  6. C语言每日一题之No.9
  7. boost function对象
  8. ELK详解(三)——Elasticsearch部署优化
  9. 数据埋点与数据需求文档
  10. 2022年计算机视觉3大趋势
  11. 小程序文档整理之 -- API(调试接口)
  12. 如何看待360与腾讯之争
  13. 中科院信工所考研经验整理(待更新)
  14. 电脑显示未连接一个服务器怎么处理,win7系统提示未能连接一个windows服务如何解决【详解】...
  15. 华为是ICT人才培养的“黑土地”,谁又是浇水人呢?
  16. 【优化求解】基于灰狼算法GWO求解最优目标matlab代码
  17. 51nod1635 第K个幸运排列
  18. SQL必知必会 - 创建表的联结
  19. 计算机专业春季高考可以报的本科学校,春季高考可以上本科吗 可以报考的学校有哪些...
  20. Win10截图工具失效怎么办?这个方法帮你轻松修复

热门文章

  1. 【力扣】合并两个有序链表
  2. 微信扫码下载APP解决方案
  3. h5浏览器——扫码功能
  4. ANSYS Help USER300
  5. 计算机网络:网络拓扑分类
  6. python条形堆积图_python – 带有中心标签的堆积条形图
  7. Centos下因为双网卡配置不当导致无法访问外网故障解决办法
  8. 利用kaptcha生成登录验证码
  9. 【科研技巧】在绘图软件中如何插入数学公式,比如Processon、Visio、draw.io
  10. 学习笔记———《最大类间方差法》