iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 24
1
Modern Web

Fabricjs 筆記系列 第 24

Day 24 - Fabricjs 實作: 自訂圖片裁切

在經過了兩天的裁切介紹,今天要來介紹另外一種方式來做圖片的裁切!

透過實作圖片裁切功能,來了解 image.crop 這個屬性的使用。

來實現能夠讓使用者自訂想要裁切的範圍。

一起來看看該怎麼做吧

新增圖片

這邊先新增一張圖片後,將 canvas 的大小動態變成圖片的原始大小。

並且新增一個和圖片一樣大的半透明遮罩讓使用者選取。

可使用 naturalWidthnaturalHeight 來取得讀取圖片的原始大小。

  img = new fabric.Image(imgEl, {
    top: 0,
    left: 0,
    selectable: false
  })
  canvas.setWidth(imgEl.naturalWidth)
  canvas.setHeight(imgEl.naturalHeight)
  userClipPath = new fabric.Rect({
    width: imgEl.naturalWidth, // 圖片原始大小
    height: imgEl.naturalHeight,
    fill: 'rgb(178, 178, 178, 0.4)',
  })
  canvas.add(img)
  canvas.add(userClipPath)

得到和圖片一樣大的 canvas 圖片

crop 屬性

crop 屬性為 fabric.Image 專屬的屬性,可以透過設定 cropXsropY 來設定裁切的起始位置,並且使用 widthheight 決定大小。

讓我們看看下面的圖解。

程式就會是這樣寫的。

img.set({
    cropX: 100,
    cropY: 100,
    width: 100,
    height: 100
  })

出來的結果會是這樣

實際使用 crop 屬性

這邊我想要讓使用者自己訂出想要裁切的範圍,所以我們可以讓使用者調整半透明矩形,調整完當使用者點選 "裁切" 按鈕後。

再去抓取目前半透明矩形的位置和形狀,並且更改圖片的 cropXcropYwidthheight 屬性,並且動態改變 canvas 的大小。

因為使用者可能不只裁切一次,所以我們需要紀錄目前裁切位置在哪邊來做累加,所以使用 nowClip 物件紀錄目前的裁切起始位置。

let nowClip = {
  x: 0,
  y: 0
}

function clipImage () {
  console.log('clip!')
  const newImgCrop = userClipPath.getBoundingRect()
  console.log(newImgCrop)
  canvas.setWidth(newImgCrop.width)
  canvas.setHeight(newImgCrop.height)
  img.set({
    cropX: newImgCrop.left + nowClip.x,
    cropY: newImgCrop.top + nowClip.y,
    width: newImgCrop.width,
    height: newImgCrop.height
  })  
  // 校正位置
  nowClip.x += newImgCrop.left
  nowClip.y += newImgCrop.top
  userClipPath.set({
    left: 0,
    top: 0
  })
  userClipPath.setCoords()
  canvas.renderAll()
}

加入其他功能

最後再加入一些常用的功能,和修改一些細節

  • 匯出圖片

須注意匯出時因為還有矩形遮罩,我這邊不讓矩形遮罩一起被匯出成圖檔的方法是將透明度先調成 0,匯出後在加入回來。

function output () {
  // 用來讓使用者看的遮罩不想入鏡
  userClipPath.opacity = 0
  const dataURL = canvas.toDataURL({
    format: `image/jpeg`,
    top: 0,
    left: 0,
    width: canvas.width,
    height: canvas.height,
    multiplier: 1
  })
  const a = document.createElement('a')
  a.href = dataURL
  a.download = `output.jpeg`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  userClipPath.opacity = 1
  canvas.renderAll()
}
  • 還原圖片
    還原圖片做法很簡單,就將 canvas 清除後,再次做原本剛進入時,新增圖片和矩形遮罩的動作。
function reset () {
  canvas.clear()
  initCanvas()
}
  • 修改邊框樣式
    最後可以在做一些矩形遮罩邊框的調整(原來的框實在不是很好看...)

參考 Day 15 - Fabricjs 物件控制項樣式調整

本日小結

今日練習使用 Image.cropXImage.cropY 達到圖片裁切的效果。

並且做出讓使用者能夠自訂裁切區塊的功能。

參考連結


上一篇
Day 23 - Fabricjs 圖形裁切進階
下一篇
Day 25 - Fabricjs 實作: 拼貼圖片
系列文
Fabricjs 筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言