国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

微信小程序圖片裁剪功能的實現

這篇具有很好參考價值的文章主要介紹了微信小程序圖片裁剪功能的實現。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


在之前的博文中,已經介紹了如何使用在前端開發(fā)中,實現較方便自由的圖片裁剪功能,可見博文: 如何一步步實現圖片裁剪功能。
本文將進一步講述在微信小程序中,我們實現圖片裁剪功能需要如何處理,文章末尾將附上小程序端圖片裁剪完整源碼的下載鏈接。
在小程序中進行圖片裁剪的效果如下圖所示:

微信小程序圖片裁剪功能的實現

圖片上傳與處理

要做圖片裁剪,首先要解決的是圖片上傳的事情,這塊在微信環(huán)境下,比較好處理,微信小程序提供了多個文件或圖片的操作接口,讓我們可以很方便的完成這個步驟。

本博之前關于小程序的圖片審核的文章:小程序圖片上傳與內容安全審核,已介紹了使用 wx.chooseMedia 接口來選擇圖片文件。
除此外,還可以有其他方式,如 wx.chooseMessageFile 接口可以從聊天記錄里選擇圖片,我們可以綜合處理如下:

function selectPhoto (callBack) {
  let itemList = [ '拍照', '從手機相冊選擇', '從聊天記錄選擇' ]
  wx.showActionSheet({
    itemList,
    success: (action) => {
      if (action.tapIndex === 0) {
        // 從拍照選擇圖片,使用 chooseMedia
        wx.chooseMedia({ sourceType: [ 'camera' ] })
      } else if (action.tapIndex === 1) {
        // 從手機相冊選擇圖片,使用 chooseMedia
        wx.chooseMedia({ sourceType: [ 'album' ] })
      } else if (action.tapIndex === 2) {
        // 從聊天記錄選擇圖片,使用 chooseMessageFile
        wx.chooseMessageFile({})
      }
    }
  })
}

其中,showActionSheet 可以顯示操作菜單,這個功能也比較常見,可以從拍照、相冊、聊天記錄里選擇文件進行加載:

微信小程序圖片裁剪功能的實現
當前,我們獲取到的是圖片文件的臨時路徑,得到圖片路徑以后,接下來要做的事情,就是如何正確適配的顯示出來。

圖片尺寸適配

由于要在前端對圖片進行裁剪,使用canvas繪制圖片也是不可少的,在繪制之前,我們需要根據圖片尺寸進行適配處理。
首先需要做的就是讀取圖片的尺寸大小,使用小程序的 wx.getImageInfo 接口即可,它能夠返回圖片原始的寬高屬性。
接著,根據圖片的寬高屬性、系統(tǒng)屏幕的寬高,一起在小程序頁面可見區(qū)域內設置圖片的縮放顯示:

// 根據窗口大小和圖片大小,設置圖片顯示尺寸以及縮放
// imgHeight 和 imgWidth 表示當前圖片的寬高
// 設置圖片顯示面板的寬高
let panelW = sys.windowWidth - 20
let panelH = sys.windowHeight - 100
if (panelH / panelW >= imgHeight / imgWidth) {
  panelH = parseInt(panelW * imgHeight / imgWidth)
} else {
  panelW = parseInt(panelH * imgWidth / imgHeight)
}
// 圖片在寬高上的縮放比,用于裁剪圖片時計算圖片實際尺寸
xScale = panelW / imgWidth
yScale = panelH / imgHeight
this.setData({
  imagePath,
  // 圖片顯示面板寬高
  panelWidth: panelW,
  panelHeight: panelH,
  // 裁剪框的寬高,初始時與圖片面板一樣
  clipWidth: panelW,
  clipHeight: panelH,
  // 裁剪的實際寬高
  croppingImageWidth: imgWidth,
  croppingImageHeight: imgHeight
})

通過以上代碼和注釋,我們知道了圖片加載時,需要計算的幾個寬高尺寸值,都是比較重要的。

圖片顯示與裁剪框

下面就可以在頁面上顯示圖片,直接展示圖片顯示區(qū)域的 wxml 代碼:

<view wx:if="{{imagePath}}" class="crop-container">
  <view class="crop-content" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}};">
    <image src="{{imagePath}}" class="pos-absolute" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}}; left: 0; top:0;"/>
    <view class="mask-bg" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}}; left: 0; top: 0;"></view>
    <view class="clip-path" style="width: {{clipWidth + 'px'}}; height: {{clipHeight + 'px'}}; left: {{clipX + 'px'}}; top: {{clipY + 'px'}};">
      <image src="{{imagePath}}" class="pos-absolute" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}}; left: {{clipImgX + 'px'}}; top: {{clipImgY + 'px'}};"/>
    </view>
    <view class="clip-box"  bind:touchmove="touchmoveM" bind:touchstart="touchstartM" style="width: {{clipWidth + 'px'}}; height: {{clipHeight + 'px'}}; left: {{clipX + 'px'}}; top: {{clipY + 'px'}};">
      <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="leftTop" class="corner-area left-top"></view>
      <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="rightTop" class="corner-area right-top"></view>
      <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="rightBottom" class="corner-area right-bottom"></view>
      <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="leftBottom" class="corner-area left-bottom"></view>
    </view>
  </view>
</view>

以上代碼中,

  • .crop-content
    外層增加圖片面板,圖片資源直接使用 <image> 組件加載,與外層面板寬高保持一致;
  • .mask-bg
    增加一個遮罩層,作為非裁剪區(qū)域的蒙層,以黑灰色透明度實現效果;
  • .clip-path
    于圖片面板內部,設置圖片的裁剪區(qū)域,這里使用的是CSS中的 clip-path 屬性,內部加載一張圖片,作為裁剪區(qū)域的圖片顯示;
    clip-path 屬性之前已有博文介紹,可以查看 clip-path屬性
  • clip-box
    設置裁剪框區(qū)域的四個corner角:左上、右上、右下和左下,里面四個元素對應這個四個角,可以對裁剪框進行縮放處理;
    當然,我們也可以在各邊的中間位置再加上操作區(qū),那一共就是8個;
  • .clip-path 圖片裁剪區(qū)與 clip-box 裁剪框需要設置位置信息,用于在移動的時候進行定位。

通過設置對應的圖片元素、蒙層、裁剪框等等,我們就已經完成了圖片裁剪的結構布局了,具體可見下圖所示:

微信小程序圖片裁剪功能的實現
圖片裁剪框設置完成后,我們需要處理的就是裁剪框的拖動與縮放事件處理了。

裁剪框的拖動與縮放

上面的 wxml 代碼中,在裁剪框的元素部分,已經增加了 touchstarttouchmove 等事件,用于在處理拖動和縮放等操作。
當我們實現裁剪框的拖動,只需要如下兩個事件:

touchstartM (event) {
  const { clipX, clipY } = this.data
  const { pageX, pageY } = event.touches[0]
  // 獲取鼠標點在裁剪框的內部位置信息
  clipBoxMoveInnerX = pageX - clipX
  clipBoxMoveInnerY = pageY - clipY
},
touchmoveM (event) {
  const { pageX, pageY } = event.touches[0]
  const { panelWidth, panelHeight, clipHeight, clipWidth } = this.data

  // 裁剪框不能脫離面板
  // X位置范圍為 0 到 (面板寬度-裁剪框寬度)
  let clipX = pageX - clipBoxMoveInnerX
  clipX = Math.max(clipX, 0)
  const panelX = panelWidth - clipWidth
  clipX = Math.min(clipX, panelX)
  // Y位置范圍為 0 到 (面板高度-裁剪框高度)
  let clipY = pageY - clipBoxMoveInnerY
  clipY = Math.max(clipY, 0)
  const panleY = panelHeight - clipHeight
  clipY = Math.min(clipY, panleY)

  // 裁剪框底圖位置信息
  const clipImgX = 0 - clipX
  const clipImgY = 0 - clipY

  this.setData({
    clipX,
    clipY,
    clipImgX,
    clipImgY
  })
}

以上代碼,通過計算圖片移動時的相對位移,重新計算裁剪框的新的位置信息,需要注意的是,移動時不要脫離外層的面板——即不能脫離圖片區(qū)域,否則無效。

縮放的操作則相對復雜一些,需要計算位移移動的距離以及當前位置下的裁剪寬高數據,并且要對每個不同的corner角進行特殊處理,這塊的完整代碼和注釋如下所示:

// 處理縮放動作中不同corner時的尺寸位置信息
getClipX (clipWidth) {
  switch (activeCorner) {
    case 'leftTop':
    case 'leftBottom':
      return clipBoxBeforeScaleClipX + (clipBoxBeforeScaleWidth - clipWidth)
    case 'rightTop':
    case 'rightBottom':
      return clipBoxBeforeScaleClipX
    default:
      return 0
  }
},
getClipY (clipHeight) {
  switch (activeCorner) {
    case 'leftTop':
    case 'rightTop':
      return clipBoxBeforeScaleClipY + (clipBoxBeforeScaleHeight - clipHeight)
    case 'leftBottom':
    case 'rightBottom':
      return clipBoxBeforeScaleClipY
    default:
      return 0
  }
},
getScaleXWidthOffset (offsetW) {
  switch (activeCorner) {
    case 'leftTop':
    case 'leftBottom':
      return -offsetW
    case 'rightTop':
    case 'rightBottom':
      return offsetW
    default:
      return 0
  }
},
getScaleYHeightOffset (offsetH) {
  switch (activeCorner) {
    case 'rightBottom':
    case 'leftBottom':
      return offsetH
    case 'rightTop':
    case 'leftTop':
      return -offsetH
    default:
      return 0
  }
},
touchstart (event) {
  const dragId = event.currentTarget.dataset.id
  const { pageX, pageY } = event.touches[0]
  const { clipX, clipY, clipHeight, clipWidth } = this.data

  // 設置縮放時臨時變量初始化值
  activeCorner = dragId
  clipBoxBeforeScalePageX = pageX
  clipBoxBeforeScalePageY = pageY
  clipBoxBeforeScaleClipX = clipX
  clipBoxBeforeScaleClipY = clipY
  clipBoxBeforeScaleWidth = clipWidth
  clipBoxBeforeScaleHeight = clipHeight
},
touchmove (event) {
  const { pageX, pageY } = event.touches[0]
  const { panelWidth, panelHeight } = this.data

  // 縮放在X上的偏移
  const xWidthOffset = this.getScaleXWidthOffset(pageX - clipBoxBeforeScalePageX)
  // 裁剪框最小寬度36
  let clipWidth = Math.max(clipBoxBeforeScaleWidth + xWidthOffset, 36)
  // 設置縮放最大寬度,放大時不能超過面板、縮小時不能超過初始裁剪框
  let tempPanelWidth = pageX > clipBoxBeforeScalePageX ? panelWidth - clipBoxBeforeScaleClipX : clipBoxBeforeScaleWidth + clipBoxBeforeScaleClipX
  // 設置裁剪框寬度
  clipWidth = Math.min(clipWidth, tempPanelWidth)

  // 縮放在Y上的偏移
  const yHeightOffset = this.getScaleYHeightOffset(pageY - clipBoxBeforeScalePageY)
  // 裁剪框最小高度36
  let clipHeight = Math.max(clipBoxBeforeScaleHeight + yHeightOffset, 36)
  // 設置縮放最大高度,放大時不能超過面板、縮小時不能超過初始裁剪框
  let tempPanelHeight = pageY > clipBoxBeforeScalePageY ? panelHeight - clipBoxBeforeScaleClipY : clipBoxBeforeScaleHeight + clipBoxBeforeScaleClipY
  // 設置裁剪框高度
  clipHeight = Math.min(clipHeight, tempPanelHeight)

  // 裁剪框位置信息
  let clipX = this.getClipX(clipWidth)
  let clipY = this.getClipY(clipHeight)
  // 裁剪框底圖位置信息
  let clipImgX = 0 - clipX
  let clipImgY = 0 - clipY

  this.setData({
    clipWidth,
    clipHeight,
    clipX,
    clipY,
    clipImgX,
    clipImgY,
    croppingImageWidth: parseInt(clipWidth / xScale),
    croppingImageHeight: parseInt(clipHeight / yScale)
  })
}

至此,圖片裁剪的功能基本完成了,能夠加載圖片、設置裁剪框、拖動和縮放裁剪框大小,計算裁剪圖片的尺寸等等。
就剩下如何真正剪裁圖片了。

增加canvas并裁剪圖片

要剪裁圖片,我們在小程序使用canvas畫布組件來處理,在頁面上增加一個canvas元素:

<canvas id="main" canvasId="main" class="main-canvas" style="width: {{croppingImageWidth + 'px'}}; height: {{croppingImageHeight + 'px'}}"></canvas>

由于這個canvas只是用來對圖片進行裁剪操作,并不需要顯示出來,我們可以把它定位到視覺窗口以外,不影響可操作的界面元素。
給畫布設置圖片裁剪所需要的寬高,通過在同等寬高下繪制圖片,就能導出圖片:

wx.showLoading({ title: '正在裁剪...' })
preCtx.clearRect(0, 0, imageWidth, imageHeight)
const width = croppingImageWidth
const height = croppingImageHeight
const xPos = Math.abs(clipImgX / xScale)
const yPos = Math.abs(clipImgY / yScale)
// 繪制裁剪區(qū)內的圖片到畫布上
preCtx.drawImage(imagePath, xPos, yPos, width, height, 0, 0, width, height)
preCtx.save()
preCtx.restore()
const that = this
preCtx.draw(false, function () {
  setTimeout(() => {
    // 將畫布導出為臨時圖片文件
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width,
      height,
      destWidth: width,
      destHeight: height,
      canvasId: 'main',
      success: (canRes) => {
        wx.hideLoading()
        that.initImage(width, height, canRes.tempFilePath)
      },
      fail (err) {
        wx.hideLoading()
        console.log(err)
      }
    })
  }, 200)
})

如上代碼所示,通過裁剪圖片的真實寬高以及相對位置信息,通過canvas的 drawImage 方法,把圖片的裁剪區(qū)域的內容繪制到畫布上,此時,該畫布就對應一張裁剪后的圖片,我們只需要把畫布導出成圖片文件即可。
導出畫布,使用 wx.canvasToTempFilePath 方法,用于將畫布導出為圖片臨時圖片文件,這個圖片文件可以重新加載或者進行導出。

保存圖片到相冊

以上過程,生成裁剪圖片的臨時文件后,就可以使用小程序提供的API,將圖片文件保存到相冊中。
只需要使用 wx.saveImageToPhotosAlbum 方法,專門用于將圖片文件保存到系統(tǒng)相冊,接收臨時文件作為參數:

wx.saveImageToPhotosAlbum({
  filePath: imgSrc,
  success: () => {
    wx.hideLoading()
    wx.vibrateShort()
    wx.showModal({
      content: '圖片已保存到相冊~',
      showCancel: false,
      confirmText: '好的',
      confirmColor: '#333'
    })
  }
})

該方法簡單方便,其中使用 wx.vibrateShort() 方法,作用是使手機發(fā)生較短時間的振動(15 ms),在小程序中也是常見的功能。
圖片保存到系統(tǒng)相冊功能完成后,我們就實現了在小程序中進行圖片剪裁的完整功能,包含加載圖片、圖片適配和裁剪框繪制、裁剪框拖動與縮放事件、圖片導出和保存的過程。

總結

本文詳細講述了在小程序中實現一個圖片裁剪功能的過程,可以看出和在瀏覽器Web端的實現差別并不大。
在核心的圖片適配、裁剪框繪制與縮放事件處理上,基本兩邊可以通用,在小程序中的實現邏輯可以完整在移到web瀏覽器上,反之亦然。
區(qū)別可能只在于圖片的加載和保存上,可以使用小程序提供的多種內置接口方法,能較方便的完成。
上文也附上了大量的核心代碼,根據這些代碼已經基本可以還原裁剪功能,如果需要完整的小程序圖片裁剪代碼,可以訪問下載:小程序圖片裁剪源碼下載文章來源地址http://www.zghlxwxcb.cn/news/detail-414525.html

到了這里,關于微信小程序圖片裁剪功能的實現的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 微信小程序 — 圖片實現縮放,拖拽功能

    movable-view 可移動的視圖容器,在頁面中可以拖拽滑動。 movable-view必須在 movable-area 組件中,并且必須是直接子節(jié)點,否則不能移動。 如果想讓圖片實現縮放,拖拽效果。則可以把圖片放到movable-view容器里面 。 movable-view 可移動的視圖容器,在頁面中可以拖拽滑動。 效果如下

    2024年02月13日
    瀏覽(23)
  • 微信小程序實現拍照并拿到圖片對象功能

    微信小程序實現拍照并拿到圖片對象功能

    微信小程序提供了函數chooseImage 我們可以在wxml中定義一個按鈕 這里綁定了一個點擊事件 叫 photograph 然后 我們在js中編寫代碼如下 這里 我們點擊后調用了wx.chooseImage 回調中接受了一個res對象 其中的tempFilePaths字段就是我們要到圖片集合 我們運行代碼 然后用手機真機調試 然后

    2024年02月07日
    瀏覽(98)
  • 微信小程序實現圖片下載與保存功能

    首先,定義了一個全局的定時器變量 timer 。 在 downloadImage 函數中,如果 timer 已經存在,就清除它,以確保每次只有一個下載任務在進行。 然后,設置一個新的定時器,延遲1秒后開始執(zhí)行下載任務。這是為了防止頻繁觸發(fā)下載操作。 在定時器的回調函數中,首先顯示一個加

    2024年02月03日
    瀏覽(51)
  • [微信小程序]在圖片上的特定區(qū)域點擊實現功能

    [微信小程序]在圖片上的特定區(qū)域點擊實現功能

    目錄 一、功能描述 二、兩種不同的解決方法 1.方法一:image組件和view組件相結合 2.方法二:獲取點擊事件的位置信息 ? 對于前端初學者,在前端設計尤其是地圖功能設計過程中,偶爾會碰到下面這個問題:實現在圖片上特定區(qū)域內的點擊進行跳轉或其它功能。對于這個問題,

    2024年02月02日
    瀏覽(169)
  • 使用taro+canvas實現微信小程序的圖片分享功能

    使用taro+canvas實現微信小程序的圖片分享功能

    二輪充電業(yè)務中,用戶充電完成后在訂單詳情頁展示訂單相關信息,用戶點擊分享按鈕喚起微信小程序分享菜單,將生成的圖片海報分享給微信好友或者下載到本地,好友可通過掃描海報中的二維碼加群領取優(yōu)惠。 使用場景及功能:微信小程序 生成海報圖片 分享好友 下載圖

    2024年02月05日
    瀏覽(704)
  • 微信小程序分享的圖片被裁切了。怎么讓他不裁剪正常比例5:4顯示

    微信小程序分享的圖片被裁切了。怎么讓他不裁剪正常比例5:4顯示

    ?現在的效果 希望的效果 ?最主要的是下面的這個函數。把圖片轉成了5:4的臨時圖片 ?頁面上。使用定位讓用戶看不到這個繪圖,但是實際上只是不出現在可視范圍內 然后調用函數把你的圖片換成這個臨時的圖片 }

    2024年02月09日
    瀏覽(87)
  • asp微信小程序上傳多張照片功能,wx.chooseMedia和wx.uploadFile配合實現多張圖片上傳

    由于項目需要使用asp,因此用asp寫了一個接收微信小程序上傳多張照片的功能,例用的是wx.chooseMedia和wx.uploadFile配合,循環(huán)上傳多張照片,微信小程序現在好像最多可以上傳20張,閑話不好上代碼,需要的可以直接下載,前后臺都有,本文只放前端代碼: 本文實現微信小程序

    2024年02月11日
    瀏覽(25)
  • uniapp 微信小程序 實現 將base64圖片保存相冊和轉發(fā)分享微信好友功能記錄 直接cv就能用?。。?!

    uniapp 微信小程序 實現 將base64圖片保存相冊和轉發(fā)分享微信好友功能記錄 直接cv就能用!?。?!

    一、base64圖片保存相冊功能 提示api:that.$refs.uToast.show用的是uview2.0的toast,可以根據具體引入的ui庫去更換; 二、轉發(fā)分享base64圖片給微信好友功能? 該功能在微信開發(fā)者工具中調試的時候會一直報錯,真機是沒問題的,可能是編譯器的bug。 其實整個wx.showShareImageMenu會拉起保

    2024年02月11日
    瀏覽(104)
  • 微信小程序內頁跳轉登錄,登錄完成后攜帶參數重新回到之前頁面實現方法

    第一步:在app.js或utils.js中添加以下兩個方法: 第二步:在跳轉到登錄頁面跳轉前調用setCallbackUrl方法(獲當前頁面的路徑和參數存本地),登錄頁面登錄成功后調用getCallBackUrl方法(提取之前存的路徑和參數返回),如果沒有就在catch中執(zhí)行登錄后的正常邏輯,比如跳轉到默

    2024年02月02日
    瀏覽(89)
  • 《微信小程序案例12》圖片識別功能

    《微信小程序案例12》圖片識別功能

    該功能是直接使用百度AI開發(fā)平臺的動物識別接口,這個接口有兩個重要的參數,一是需要獲取access_token、二是需要把上傳的圖片編碼為base64。而獲取access_token有需要使用另一個接口來獲取,獲取到后我使用緩存技術把這個acces_token保存起來,并設置一個有效時間。 ? ? ?新用

    2024年02月11日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包