成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

使用 JavaScript 根據(jù)用戶照片和姓名生成海報(bào)

rickchen / 2363人閱讀

摘要:前言最近在為公司的一個(gè)比賽制作專(zhuān)題頁(yè),碰到一個(gè)使用參賽者上傳的照片生成專(zhuān)屬海報(bào)的需求,實(shí)現(xiàn)過(guò)程中用到了一些以前沒(méi)用過(guò)的,也踩了一些坑,于是將其記錄下來(lái)。

前言

最近在為公司的一個(gè)比賽制作專(zhuān)題頁(yè),碰到一個(gè)使用參賽者上傳的照片生成專(zhuān)屬海報(bào)的需求,實(shí)現(xiàn)過(guò)程中用到了一些以前沒(méi)用過(guò)的 api,也踩了一些坑,于是將其記錄下來(lái)。

需求描述

用戶點(diǎn)擊按鈕進(jìn)行照片上傳

照片上傳完成后,將照片進(jìn)行裁剪,并和海報(bào)背景、姓名等組合得到海報(bào)

將生成的海報(bào)上傳

效果大概如下:

海報(bào)背景:

成品:

實(shí)現(xiàn)過(guò)程 1、初始化 canvas
canvas#poster-canvas(width="960" height="1280")
function initCanvas() {
  canvasCtx = document.getElementById("poster-canvas").getContext("2d");
}
2、繪制海報(bào)背景

海報(bào)背景為預(yù)先提供的一張照片,將其設(shè)置到一個(gè)隱藏的 img 標(biāo)簽里面,并且預(yù)留一個(gè) canvas 元素用于繪制海報(bào):

img.poster-background(src="/assets/xxx/poster-background.jpeg")

頁(yè)面加載完成后,將海報(bào)背景繪制到 canvas 內(nèi):

$("img.poster-background").on("load", function () {
  var backgroundImg = $("img.poster-background")[0];
  canvasCtx.drawImage(backgroundImg, 0, 0, 960, 1280);
  renderName();
});

海報(bào)背景繪制完成之后,需要將用戶姓名繪制到特定位置。由于用戶姓名長(zhǎng)度不一,因此需要進(jìn)行計(jì)算確定字體大?。?/p>

function renderName() {
  var name = $("input[name="chName"]").val();
  var fontSize;
  if (name.length < 3) {
    fontSize = 100;
  } else {
    fontSize = parseInt(320 / name.length);
  }
  canvasCtx.font = "bold " + fontSize + "px Courier New";
  canvasCtx.fillStyle = "#de071b";
  canvasCtx.fillText(name, 20, 1066);
}
3、上傳照片

使用 file 類(lèi)型的 input 元素,因?yàn)轫?yè)面上表現(xiàn)為點(diǎn)擊按鈕,因此使用經(jīng)典的將 input 元素透明化并覆蓋按鈕的方法:

a.upload-btn 
  input#photo(type="file" name="photo" accept="image/jpeg, image/png")
  | 上傳自己的照片生成專(zhuān)屬海報(bào)
.upload-btn input {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  width: 100%;
  height: 68px;
  cursor: pointer;
}

然后監(jiān)聽(tīng) input 元素的 change 事件,然后使用 FormData API 構(gòu)造表單數(shù)據(jù),使用 ajax 進(jìn)行異步上傳,照片上傳完成之后。得到一個(gè)地址,將這個(gè)地址設(shè)置到頁(yè)面上預(yù)留的一個(gè) img 標(biāo)簽里面:

$("#photo").on("change", function (e) {
  var file = e.target.files[0];
  var type = file.type;
  if (type !== "image/jpeg" && type !== "image/png") {
    window.toastr.error("請(qǐng)上傳 jpg 或 png 格式的圖片");
  } else {
    var formData = new FormData();
    formData.append("avatar", file);
    $.ajax({
      type: "POST",
      url: "/upload_url",
      data: formData,
      contentType: false,
      processData: false,
      success: function(result) {
        var avatarUrl = result.data.url;
        $("img.avatar").attr("src", avatarUrl);
      },
      error: function(err) {
        
      }
    });
  }
});
4、繪制照片

海報(bào)中放置照片的區(qū)域?yàn)檎叫危怯脩羯蟼鞯恼掌瑓s不一定,因此需要對(duì)照片進(jìn)行裁剪,裁剪的原則為取照片中間部分。然后將裁剪參數(shù)傳進(jìn) canvasdrawImage 方法,進(jìn)行繪制:

$("img.avatar").on("load", function () {
  var avatarImg = $("img.avatar")[0];
  var originWidth = avatarImg.width;
  var originHeight = avatarImg.height;
  var newWidth, cutStartX, cutStartY;

  if (originWidth < originHeight) {
    newWidth = originWidth;
    cutStartX = 0;
    cutStartY = (originHeight - originWidth) / 2;
  } else if (originWidth > originHeight) {
    newWidth = originHeight;
    cutStartX = (originWidth - originHeight) / 2;
    cutStartY = 0;
  } else {
    newWidth = originWidth;
    cutStartX = 0;
    cutStartY = 0;
  }
  
  canvasCtx.drawImage(avatarImg, cutStartX, cutStartY, newWidth, newWidth, 0, 0, 960, 960);

  uploadPoster();
      
});  

前面繪制海報(bào)背景和這里繪制照片,調(diào)用的是同一個(gè)方法,只不過(guò)后者多傳進(jìn)去了裁剪參數(shù)。但是需要注意的是,裁剪參數(shù)是在繪制位置之前傳進(jìn)去的,而不是簡(jiǎn)單的補(bǔ)在后面:

canvasCtx.drawImage(backgroundImg, 0, 0, 960, 1280);

canvasCtx.drawImage(avatarImg, cutStartX, cutStartY, newWidth, newWidth, 0, 0, 960, 960);
5、上傳海報(bào)

依然使用 FormData API,因此需要先用 canvas 構(gòu)造一個(gè) Blob 對(duì)象。新版本的 Chrome 和 Firefox 支持 canvastoBlob 方法,可以直接使用:

document.getElementById("poster-canvas").toBlob(function (blob) {});

其它瀏覽器里,可以先用 toDataURL方法得到 base64 格式的圖片數(shù)據(jù),再轉(zhuǎn)為 Blob

var blob = dataURLtoBlob(document.getElementById("poster-canvas").toDataURL());

function dataURLtoBlob(dataurl) {
  if (dataurl.indexOf("base64") < 0) {
    dataurl = "data:image/jpeg;base64," + dataurl;
  }
  var arr = dataurl.split(",");
  var mime = arr[0].match(/:(.*?);/)[1];
  var bstr = atob(arr[1]);
  var n = bstr.length;
  var u8arr = new Uint8Array(n);
  while (n --) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {type: mime});
}

然后進(jìn)行上傳,步驟和前面上傳照片一致:

var formData = new FormData();
formData.append("poster", blob);
$.ajax({
  type: "POST",
  url: "/upload_poster_url",
  data: formdata,
  contentType: false,
  processData: false,
  success: function(result) {
    
  },
  error: function(err) {
    
  }
});

至此,整個(gè)流程完結(jié)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86919.html

相關(guān)文章

  • 手對(duì)手的教你用canvas畫(huà)一個(gè)簡(jiǎn)單的海報(bào)

    摘要:啦啦啦,首先說(shuō)下需求,產(chǎn)品想讓用戶在我們內(nèi),分享一張圖片到微信等平臺(tái)。圖片中包含用戶的姓名頭像和帶著自己信息的二維碼。然后,如何生成這張海報(bào)呢首先我們老大告訴我有一個(gè)插件叫其作用就是可以將節(jié)點(diǎn)轉(zhuǎn)化成圖片,是個(gè)不錯(cuò)的東西。 啦啦啦,首先說(shuō)下需求,產(chǎn)品想讓用戶在我們app內(nèi),分享一張圖片到微信、qq等平臺(tái)。圖片中包含用戶的姓名、頭像、和帶著自己信息的二維碼。然后,如何生成這張海報(bào)呢~~~首...

    verano 評(píng)論0 收藏0
  • 手對(duì)手的教你用canvas畫(huà)一個(gè)簡(jiǎn)單的海報(bào)

    摘要:啦啦啦,首先說(shuō)下需求,產(chǎn)品想讓用戶在我們內(nèi),分享一張圖片到微信等平臺(tái)。圖片中包含用戶的姓名頭像和帶著自己信息的二維碼。然后,如何生成這張海報(bào)呢首先我們老大告訴我有一個(gè)插件叫其作用就是可以將節(jié)點(diǎn)轉(zhuǎn)化成圖片,是個(gè)不錯(cuò)的東西。 啦啦啦,首先說(shuō)下需求,產(chǎn)品想讓用戶在我們app內(nèi),分享一張圖片到微信、qq等平臺(tái)。圖片中包含用戶的姓名、頭像、和帶著自己信息的二維碼。然后,如何生成這張海報(bào)呢~~~首...

    BlackHole1 評(píng)論0 收藏0
  • 手對(duì)手的教你用canvas畫(huà)一個(gè)簡(jiǎn)單的海報(bào)

    摘要:啦啦啦,首先說(shuō)下需求,產(chǎn)品想讓用戶在我們內(nèi),分享一張圖片到微信等平臺(tái)。圖片中包含用戶的姓名頭像和帶著自己信息的二維碼。然后,如何生成這張海報(bào)呢首先我們老大告訴我有一個(gè)插件叫其作用就是可以將節(jié)點(diǎn)轉(zhuǎn)化成圖片,是個(gè)不錯(cuò)的東西。 啦啦啦,首先說(shuō)下需求,產(chǎn)品想讓用戶在我們app內(nèi),分享一張圖片到微信、qq等平臺(tái)。圖片中包含用戶的姓名、頭像、和帶著自己信息的二維碼。然后,如何生成這張海報(bào)呢~~~首...

    cyixlq 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

rickchen

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<