1. 程式人生 > >使用canvas將照片和海報邊框圖片合成海報的移動端例子

使用canvas將照片和海報邊框圖片合成海報的移動端例子

需求:
類似一些美圖軟體中的給照片加相框的操作
1. 使用者選擇照片,照片可以移動、可以放大縮小
2. 選擇海報模版
3. 生成海報
最後生成的海報效果圖類似下圖
這裡寫圖片描述

使用的技術棧是:vue+html2canvas+exif-js
具體思路和程式碼:

html部分,思路和邏輯在程式碼下面寫著

<template>
    <section>
        <div id='posterwrap' v-show='!sharing' ref="wrap">
            <div  ref='posterwrap-inner'
class="posterwrap-inner">
<p v-show='!temp.imgsrc' @click='chooseimg'></p> <!-- 照片預覽區 --> <div class="preview-img-wrap"> <img @touchstart.prevent.stop='touchStart($event, 0)' @touchmove.prevent.stop='touchMove($event, 0, -1)'
@touchend.prevent.stop='touchEnd($event, 0)' :style='{width: 99 * myphoto.scale + "%", height: 99 * myphoto.scale + "%", left: myphoto.x + "px", top: myphoto.y + "px"}' :src="myphoto.imgsrc" id='preview' alt="" ref="img" >
</div> <!-- 選擇的海報模版 --> <img
@touchstart.prevent.stop='touchStart($event, 0)' @touchmove.prevent.stop='touchMove($event, 0)' @touchend.prevent.stop='touchEnd($event, 0)' :src="temp" alt="" class="tag-item">
</div> </div> <!-- 海報模版區 --> <div class="footer"> <div id="tags-preview"> <img class="tag-item" @click='addTag' src="@/assets/img/temp1.png" alt=""> <img class="tag-item" @click='addTag' src="@/assets/img/temp2.png" alt=""> </div> <!-- 按鈕區 --> <div class="banner"> <div @click='rephoto' data-xeslog-params="key=click-upload-img" class="rephoto footer-btn">重新選圖</div> <div class="share footer-btn" @click='screenshots' data-xeslog-params="key='click-finish-share'">製作完成</div> </div> </div> </div> <!-- canvas區 僅用作工具 --> <canvas id='canvas'></canvas> <canvas id='canvas2'></canvas> <canvas id='canvas3' style="display:none"></canvas> <!-- 默默調起使用者圖片的input --> <input type="file" value="" accept="image/*" id='chooseimg' @change='previewFile'> <!-- 最終生成的海報 --> <div v-if='share' data-xeslog-params="key=click-share-img" class="result"> <p class="share-tit">長按儲存海報</p> <p >分享到朋友圈,有機會返還學費哦</p> <div class="myposter-wrap"> <img v-if="this.$route.query.isapp == 0" id='myposter' :src="myposterlast" alt=""> </div> </div> <!-- 提示層區 --> <div class="shadow" v-if="finish"> <div class="post-doing" v-if="finish"> <img src ="@/assets/img/loading.gif" alt=""> <p>
{{shadow}}</p> </div> </div> </section> </template>

1.點選’選擇圖片’的按鈕時候,實際觸發的是<input type="file">,在input的change事件裡面,使用new FileReader()讀取圖片的bsae64,如果調起的是使用者的相機拍照照片,在各別機型上傳出來的照片會有90度或180度旋轉的現象,解決這一問題使用的是exif-js來將旋轉了的圖片放正。然後得到正確位置的圖片的base64賦給圖片預覽區的img
2. 通過上面的步驟,我們可以在預覽區生成了預覽的圖片,接下來要實現的是點選需要的海報模版相框,這個邏輯比較簡單,就是將點選的模版src賦給模版img
3. 模版選擇好了,接下來要進行照片的編輯了,照片的縮放和移動,相對還是比較難寫一些的,通過touchstart事件的e.touches來判斷是否為多指操作和兩指之間的距離判斷來判定是縮放還是移動。如果是縮放,需要計算放大的比例。如果是移動,需要計算移動的比例,具體程式碼如下

_getDistance (xLen, yLen) {//計算距離
       return Math.sqrt(xLen * xLen + yLen * yLen)
      },
touchStart (e, index) {//縮放或者移動
        if (e.touches.length > 1) {
            let point1 = e.touches[0]
            let point2 = e.touches[1]
            let xLen = Math.abs(point2.pageX - point1.pageX)
            let yLen = Math.abs(point2.pageY - point1.pageY)
            this.myphoto.touchDistance = this._getDistance(xLen, yLen)
          } else {
            this.myphoto.move = 1
            this.myphoto.sx = e.touches[0].pageX
            this.myphoto.sy = e.touches[0].pageY
          }
        }
    },
    touchMove (e, index, direction) {//拖動
        direction = direction == -1 ? -1 : 1
        if (e.touches.length > 1) {
          let xLen = Math.abs(e.touches[0].pageX - e.touches[1].pageX)
          let yLen = Math.abs(e.touches[1].pageY - e.touches[1].pageY)
          let touchDistance = this._getDistance(xLen, yLen) - this.myphoto.touchDistance
          if (this.myphoto.touchDistance) {
            let scale = Math.abs(this.myphoto.scale + touchDistance / 3000)
            this.myphoto.scale = (scale > 3 ? 3 : scale < 0.5 ? 0.5 : scale)
          }
    } else {
        this.myphoto.x -= (this.myphoto.sx - e.touches[0].pageX) * direction
        this.myphoto.y -= (this.myphoto.sy - e.touches[0].pageY) * direction
        this.myphoto.sx = e.touches[0].pageX
        this.myphoto.sy = e.touches[0].pageY
    }
    },
    touchEnd (e, index) {//行為結束
        this.myphoto.touchDistance = 0
        this.myphoto.move = 0
        if (e.touches.length) {
            this.myphoto.move = 1
            this.myphoto.sx = e.touches[0].pageX
            this.myphoto.sy = e.touches[0].pageY
        }
    },

4.再接下來就是截圖來,將有了照片的模版使用html2canvas截圖

screenshots () {
            var _this = this
            var wrap = document.getElementById('posterwrap')
            var canvas = document.getElementById('canvas')
            _this.finish = 1
            _this.shadow = '正在努力製作海報'
            canvas.width = wrap.offsetWidth * 2 + 5
        canvas.height = wrap.offsetHeight * 2 
        canvas.style.width = wrap.offsetWidth + 'px'
          canvas.style.height = wrap.offsetHeight + 'px'
          console.log(canvas)
          var context = canvas.getContext('2d')
          context.scale(2, 2)
          context.translate(-20, -10)
      html2canvas(_this.$refs['posterwrap-inner'], {
          allowTaint: true,
          taintTest: false,
          backgroundColor: null,
        //   dpi: 3000,
          scale: 2,
          canvas: canvas,
          width: canvas.width,
          height:   canvas.height,
          removeContainer: false,
          useCORS: true,      
          onrendered: function (canvas) {//將截圖圖片的base64給生成區
            var dataUrl = canvas.toDataURL('image/jpg')
                    _this.sharing = 1
                    _this.myposterlast = dataUrl
            _this.share = 1
            _this.myphoto = {
                touchDistance: 0,
                scale: 1,
                move: 0,
                x: 0,
                y: 0,
                sx: 0,
                sy: 0,
                imgsrc: ''
            }
            _this.taglist = _this.myphoto
          }
            })
        },

其中有遇到一個很坑的問題:html2canvas截圖圖片有白邊/黑邊 的問題

相關推薦

使用canvas照片海報邊框圖片合成海報移動例子

需求: 類似一些美圖軟體中的給照片加相框的操作 1. 使用者選擇照片,照片可以移動、可以放大縮小 2. 選擇海報模版 3. 生成海報 最後生成的海報效果圖類似下圖 使用的技術棧是:vue

利用canvas把二維碼圖片合成海報

思路:在微信中登入,後臺傳來的是一個連結、一個名字、一張圖片。把圖片當做背景,畫滿整個畫布。之後需要把連結轉為二維碼,使用jq.qrcode轉化,轉化完成後是一個canvas,把這個canvas再轉成一張圖片,畫到大的畫布上。把名字畫到畫布上。把整張畫布轉為圖片。一、定義畫布

利用canvashtml頁面截成圖片——問題已成功解決

現在需要做一個功能: 一個html頁面有多個div,每個div裡面都含有用echarts畫的圖表,現在要對這個html頁面進行自動截圖 我在網上找到了一個方法: <!DOCTYPE html> <html> <head> <meta ch

h264aac碼流合成flv檔案

在視訊應用中,經常需要將接收到h264和aac資料儲存成檔案。 本來想用mp4格式,但是mp4在沒有正常關閉的情況下會導致檔案打不開,而在實際應用中經常會出現裝置直接拔電,程式不是正常結束的情況。於是想用採用flv格式,flv相對mp4簡單很多,參照ffmpeg裡的flv自

Vue-cli px轉化為rem,適配移動(vue-cli2.x vue-cli3中的使用)

一. Vue-cli2.x中的用法 1.下載lib-flexible 我使用的是vue-cli+webpack,所以是通過npm來安裝的 npm i lib-flexible --save 2.引入lib-flexible 在main.js中引入lib-flexib

Vue:px轉化為rem,適配移動vant-UI等框架(px2rem-loader)

轉載:https://www.cnblogs.com/WQLong/p/7798822.html 1.下載lib-flexible 使用的是vue-cli+webpack,通過npm來安裝的 npm i lib-flexible --save 2.引入lib-flexible 在main.

Vue:px轉化為rem,適配移動

1.下載lib-flexible我使用的是vue-cli+webpack,所以是通過npm來安裝的npm i lib-flexible --save2.引入lib-flexible在main.js中引入lib-flexibleimport 'lib-flexible/flex

px2rem-loader(Vue:px轉化為rem,適配移動

轉載:https://www.cnblogs.com/WQLong/p/7798822.html 1.下載lib-flexible 使用的是vue-cli+webpack,通過npm來安裝的 npm i lib-flexible --save 2.引入lib-flexible 在

60.Vue:px轉化為rem,適配移動

1.下載lib-flexible 我使用的是vue-cli+webpack,所以是通過npm來安裝的 npm i lib-flexible --save 2.引入lib-flexible 在main.js中引入lib-flexible import 'lib-flexible/fle

C# 生成海報,文本區域指定換行,圖片合成

response money .com file rec map tin textarea args protected void Page_Load(object sender, EventArgs e) { if (!I

<canvas合成海報>所遇問題及解決方案總結

設置 iphone 出現問題 保存 白屏 全屏 分享 ase .get 最近做了一個用canvas合成海報圖片的移動端項目,由於一點canvas基礎都沒有,所以去網上搜了一位前輩的demo,但是開發過程中遇到了很多問題,現將所遇問題及解決方法總結如下: 1、移動端c

自從會了Python之後,我就沒用過PS了!帶你照片變成卡通圖片

取數 雙邊濾波器 也會 apt 雙邊濾波 合並 區域 彩色 減少 第1步:減少圖像色彩 因為雙邊濾波器平滑平坦區域同時能保持邊緣清晰,所以很適合於將RGB圖像轉換為卡通。雖然速度好像慢一些一個技巧是重復(例如,通過num_bilateral = 7七次)應用

linlayout佈局轉為bitmap圖片儲存

1.首先新建路徑 File filedirs = new File(Environment.getExternalStorageDirectory(), "/YuLin/"); if (!filedirs.exists()) { filedirs.mkdirs

PHP合成活動商品圖片分享海報

      不說廢話,直接上程式碼 <?php $data = [ 'title' =>'【2雙裝】秋冬棉拖條紋/格子【8色可選】', 'price_market' => '¥34.9', 'price_member'

duilibxml圖片合併到exe資源中或者dll中

直接上demo的編寫步驟了。 1.建立一個win32的空的工程用作demo工程。從其他工程複製stdafx.h、stdafx.cpp、testmain.cpp、mainwnd.h、mainwnd.cpp檔案過來使用。我是從TestAlphaWindow工程中複製過來的。 2.新增現有檔案

CxImage透明圖片合成文字疊加

1         CxImage的作用 CxImage將幾張圖片合成一張圖片,在一張底圖上新增圖片,有些圖片是有透明效果的,實現圖片之間的透明重疊效果。另外還可以新增文字。 (1)背景圖片mymix.png  

java多張圖片合成視訊

java將多張圖片合成視訊 需求 近幾天,無聊就看看抖音,視訊資訊傳播資訊,相親去抖音,網紅去抖音,秀恩愛去抖音。。。走在大街上,幾個小妹妹拿著手機自拍幹是玩抖音還是直播呢?每個人都想當導演的夢,但又沒DV的錢,又沒導演的才華,就是有夢。拍照你總會吧,就想能不能把自己幾張的照片,

使用opencv實現視訊分解圖片圖片合成視屏

# 視訊分解成圖片 import cv2 cap = cv2.VideoCapture("22.mp4") # 獲取開啟的控制代碼 isOpened = cap.isOpened # 判斷是否開啟 print(isOpened) fps = cap.get(cv2.CAP_PROP_FPS) w

Android Camera 自動適配多種螢幕,解決預覽照片拉伸儲存的圖片拉伸

最近公司需要做一個手機自拍照的功能,由於之前有做過類似手機拍照的功能,所以很快就實現了自定義手機拍的功能。但是後面發現部分手機出現預覽照片拉伸和儲存的圖片拉伸的情況。然後百度了一下,發現原理很好理解,也有一堆demo,然而並沒有解決拉伸的情況。下面總結一下我的解決方法,希望對

canvas html繪制圖片 生成圖片鏈接

分享 技術分享 meta div 圖片 asc ext raw 屏幕 廢話不多說,直接上代碼 其中圖片地址換成你的,自己玩兒去吧 <!DOCTYPE html> <html> <head> <meta charset="U