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

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

%7Bthis.state.sourceImg.src%7D

复制代码

效果:

7ea07d2280c6a6b1d9e0ad81716cd8b2.png

411398a5fb2a670a36d0c23f072997a4.png

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个参数

fbb207f20e22a4084447795c116bca01.png

daefc0e98df9ff1c00bba6842762d45f.png

如图示,上传了一张尺寸小且为正方形的图片,先根据背景图片计算宽高比,在用户图片中裁剪出一个宽高比与背景图片宽高比一样的最大范围,并且裁剪图片中心部分,获得开始裁剪的点,左上角这个点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

})

};

复制代码

1a71129b51b333468cd6c109199dde19.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pyqt5窗口之间传递信号_pyQT5 实现窗体之间传值的示例

准备一个MainWindow和一个WidgetForm&#xff0c;总代码如下# -*- coding: utf-8 -*-from PyQt5 import QtWidgetsfrom main_windows import Ui_MainWindowimport sysfrom wid_defs import my_widgetsfrom dlg_defs import my_Dialogclass MyWindow(QtWidgets.QMainWindow,Ui_M…

matlab length_MATLAB入门

一、操作界面1.功能区 2.当前文件夹 3.命令窗口4.工作区 5.程序编辑窗口 6.脚本文件&#xff08;1&#xff09;当前文件夹是MATLAB读取和存储文件的默认文件夹。 &#xff08;2&#xff09;当前文件夹可以修改或新建命令行窗口&#xff1a;用于输入命令&#xff08;或语句&…

html微信支付功能代码,js微信支付实现代码

微信支付//调用微信JS api 支付function jsApiCall(){WeixinJSBridge.invoke("getBrandWCPayRequest",{$parms},//下面是支付完成后的回调&#xff0c;可以直接提示成功function(res) {if(res.err_msg "get_brand_wcpay_request:ok") {location.href &qu…

python控制语句第一章_python基础第一章

Python基础第一个python程序变量程序交互基本数据类型格式化输出基本运算符流程控制if...else...流程控制-循环第一个python程序文件执行1.用notepad创建一个文件&#xff0c;输入以下代码&#xff1a;print(HelloWorld)print(python好简单啊&#xff0c;我要学好挣大钱&#x…

docker 端口映射 udp_Docker 制作一键安装的本地无污染 DNS 域名服务

国庆休假回来&#xff0c;感觉和整个世界失联了&#xff0c;各种不通&#xff0c;不得不就自己本地的应用环境进一步的升级&#xff1a;搭建一个本地版本的无污染 DNS 域名服务。各种网络文章扫了一遍&#xff0c;推荐以下这篇文章&#xff1a;CoreDNS搭建无污染DNS指导思想基本…

jquery 验证小数点后几位_(亲测可用)input只能输入数字或小数点后几位

webapp是基于html5网页版的app&#xff0c;经常会结合app成为混合模式 hybrid app&#xff0c;也就是 app小应用打开 访问的其实是网页&#xff0c;这种方式非常不错&#xff0c;解决了app更新的难题&#xff0c; 所以这个时候要求 webapp需要做的非常像原生app一样。下面是切图…

快能通小学生计算机的游戏,亲子小游戏,帮助孩子更快学会交通安全知识

随着我国机动化进程加快和小汽车进入千家万户&#xff0c;如何安全乘坐机动车&#xff0c;如何在上放学途中保障儿童青少年的交通安全&#xff0c;成为儿童青少年交通安全保护的重要内容。下面小编介绍几个亲子小游戏&#xff0c;帮助孩子更快学会交通安全知识。认识交通标志游…

es 怎么嵌入 算法模型_快速ES-RNN: ES-RNN算法的GPU实现

快速ES-RNN: ES-RNN算法的GPU实现题目&#xff1a;Fast ES-RNN: A GPU Implementation of the ES-RNN Algorithm作者&#xff1a;Andrew Redd, Kaung Khin, Aldo Marini来源&#xff1a;Machine Learning (cs.LG)Submitted on 7 Jul 2019文档链接&#xff1a;arXiv:1907.03329代…

latex 三线表_LaTeX学习记录(3):使用图表

学习记录(3)&#xff1a;使用图表每次跟朋友安利 的时候我都会讲这么一个故事&#xff1a;❝当时设计天琴一号加速度计的控制器参数&#xff0c;出于数字控制参数切换的便利性&#xff0c;疯狂设计了十几套参数。然而写报告的时候傻了&#xff1a;老板要求每套参数六个自由度的…

计算机终端网络准入控制要求,计算机网络终端准入控制技术资料.pdf

201 计算机系统应用1年第20卷第l期http&#xff1a;&#xff0f;&#xff0f;www&#xff0e;c-Sa&#xff0e;org&#xff0e;cn计算机网络终端准入控制技术①周超&#xff0c;周城&#xff0c;丁晨路(重庆通信学院研究生管理大队&#xff0c;重庆400035)摘要&#xff1a;终端…

kubernetes怎么读_每个 Kubernetes 应聘者应该知道的 5 个面试题 | Linux 中国

如果你是要面试 Kubernetes 相关职位的应聘者&#xff0c;这里给出了要提问的问题以及这些问题的重要性。-- Jessica Repka面试对面试官及候选人来说都很不容易。最近&#xff0c;我发现面试 Kubernetes 相关工作的候选人似乎尤其困难。为什么呢&#xff1f;一方面&#xff0c;…

英语作文谈谈你对计算机的看法,英语作文:谈谈你对网络语言的看法

英语作文&#xff1a;谈谈你对网络语言的看法在学习、工作、生活中&#xff0c;大家或多或少都会接触过作文吧&#xff0c;作文要求篇章结构完整&#xff0c;一定要避免无结尾作文的.出现。一篇什么样的作文才能称之为优秀作文呢&#xff1f;以下是小编帮大家整理的英语作文&am…

华为云域名注册_华为云域名专场钜惠,助推中小企业云速建站

域名不仅是一个简单的网址&#xff0c;更是企业在市场竞争中获得持久优势的有力工具。所以对于中小企业而言&#xff0c;拥有一个优质的域名对企业发展而言是很重要的。为了帮助中小企业轻松注册域名&#xff0c;快速搭建好网站&#xff0c;让用户在最短的时间内&#xff0c;最…

html button跳转页面_HTML跳转到页面指定位置的几种方法

前言有时候&#xff0c;我们想阅读页面中某段精彩的内容&#xff0c;但由于页面太长&#xff0c;用户需要自己滚动页面&#xff0c;查找起来非常麻烦 &#xff0c;很容易让人失去继续往下阅读的兴趣。这样体验非常不好&#xff0c;所以我们可以想办法 实现点击某段文字或者图片…

用计算机新字库打出的文字,为什么用五笔打字有很多字打不出来(GBK和GB2312字库的区别)...

五笔输入法有很多版本&#xff0c;有的版本只能输入GB2312字库中的字(6763个字)&#xff0c;大部分版本的五笔输入法能输入GBK字库中的字(21003个字)。所以只要你选用支持GBK字库的五笔输入法&#xff0c;一般的繁体字和偏僻字就能输入了。简单一点的说&#xff1a;两个原因&am…

c语言exit_看了这几个C语言例子,你一定会说5个哇塞,声音一次比一次大

曾经我一直以为自己C语言学的还挺好的&#xff0c;直到看到这几个例子。例1首先来看一下&#xff0c;大师是如何求圆周率的&#xff0c;一口君实在词穷&#xff0c;first哇塞。#include long a10000,b0,c10000,d,e,f[10001],g; void main() { for(;b ! c; f[b] a…

webis个人主页设计_个人网站设计及实现毕业设计论文

知识不仅是指课本的内容,还包括社会经验、文明文化、时代精神等整体要素,才有竞争力,知识是新时代的资本,五六十年代人靠勤劳可以成事&#xff1b;今天的香港要抢知识,要以知识取胜个人网站设计及实现作者&#xff1a;张铎指导教师&#xff1a;刘向娇摘要&#xff1a;网络发展到…

html整合vue elementui,vue2.0结合Element-ui实战案例

前言我们将会选择使用一些 vue 周边的库vue-cli, vue-router,axios,moment,Element-ui搭建一个前端项目案例&#xff0c;后端数据接口&#xff0c;会使用json-server快速搭建一个本地的服务&#xff0c;方便对数据的增删改查&#xff0c;利用以上技术我们会搭建一个vue案例&…

python基本判断语句_python基础4 - 判断(if)语句

6. 判断&#xff08;if&#xff09;语句 6.1 if 判断语句基本语法 在 Python 中&#xff0c;if语句 就是用来进行判断的&#xff0c;格式如下&#xff1a; if 要判断的条件: 条件成立时&#xff0c;要做的事情 …… 注意&#xff1a;代码的缩进为一个 tab 键&#xff0c;或者 4…

nginx nodejs环境配置_服务器环境配置安装(mysql+redis+nodejs+nginx)

公司用来测试的服务器挂了&#xff0c;最后重装了系统&#xff0c;需要重新配置程序运行环境&#xff0c;linux上安装不是很熟悉&#xff0c;特此记录一下。首先获取系统版本信息&#xff1a;一、mysql1. 安装安装命令&#xff1a;sudo apt-get install mysql-server在安装过程…