記事ディレクトリ
序文
このアプレットは、写真をアップロードしたり、写真を撮ってアップロードしたりすることができ、H5 と互換性のある写真のアップロードおよび写真の圧縮メソッドが付属しています。
1.アルバムの選択と写真撮影をサポートします
アルバムの選択と写真の撮影をサポートします uniapp が提供する API を使用できます もちろん、自分で希望のスタイルをパッケージ化することもできます ここでは uni のメソッドを直接使用します uni.chooseImage
構成sourceType: ['album', 'camera']
openSelectImage() {
let tempList = []
uni.chooseImage({
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
if (res.tempFilePaths?.length > 0) {
tempList = res.tempFilePaths
// #ifdef MP
this.recursionCompressMP(tempList, (e) => {
console.log('压缩后结果-----', e)
})
// #endif
// #ifdef H5
this.recursionCompressH5(tempList, (e) => {
console.log('压缩后结果-----', e)
})
// #endif
}
},
fail: (err) => {
console.log("err: ------", err);
}
})
}
// 微信
async recursionCompressMP(urlList, callback) {
let imgCompressList = []
let imageSize = 0
for (let itemUrl of urlList) {
const result = await this.jumpImageCompress(itemUrl)
if (result?.size < 150000) {
this.tempImageList.push(itemUrl)
continue
}
await this.getUserImageCompress(itemUrl, callback, result?.size)
}
},
圧縮された画像は主に、キャンバスが提供するAPI
1 とuni.createCanvasContextを使用して、キャンバス描画コンテキストを作成します。
2. CanvasContext.drawImage は、画像をキャンバスに描画します。
3. CanvasContext.draw は、描画コンテキスト内の以前の記述 (パス、変形、スタイル) をキャンバスに描画します。
4. キャンバスが描画されたら、キャンバスを画像としてエクスポートし、現在のキャンバスの指定された領域の内容をエクスポートして、指定されたサイズの画像を生成し、ファイル パスを返します。uni.canvasToTempFilePath
//微信压缩图片
getUserImageCompress(itemUrl, callback, size){
let that = this;
return new Promise ((resolve, reject)=>{
uni.getImageInfo({
src: itemUrl,
success: (res) => {
//获取设备像素比,不获取最后图片展示有问题
uni.getSystemInfo({
success: function(info) {
let ratio = 2;
let canvasWidth = res.width //图片原始长宽
let canvasHeight = res.height
let compressWidth = res.width
let quality = 0.1
compressWidth = res.width - 120
canvasHeight = res.height - 120
while (canvasWidth > compressWidth || canvasHeight > canvasHeight) {
// 保证宽高在400以内
canvasWidth = Math.trunc(res.width / ratio)
canvasHeight = Math.trunc(res.height / ratio)
ratio++;
}
that.canvasWidth = canvasWidth
that.canvasHeight = canvasHeight
let ctx = uni.createCanvasContext('mycanvas')
ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight)
ctx.draw(false, setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: 'mycanvas',
destWidth: canvasWidth,
destHeight: canvasHeight,
fileType: 'jpg',
quality: quality,
success: function(res1) {
callback && callback(res1.tempFilePath) //拿到图片压缩后的临时路径
uni.getFileInfo({
filePath: res1.tempFilePath,
success: (ress) => {
console.log('压缩之后----',ress) //返回图片尺寸
callback && callback(res1.tempFilePath)
console.log('添加数据----', that.tempImageList)
resolve(res1.tempFilePath)
that.tempImageList.push(res1.tempFilePath)
}
})
},
fail: function(res) {
console.log('canvas错误---',res.errMsg)
}
})
}, 100)) //留一定的时间绘制canvas
}
})
},
fail: (e) => {
console.log('错误----', e)
}
})
})
},
返された画像サイズを使用して圧縮率を制御し、圧縮関数を繰り返し実行します。
//返回图片大小
jumpImageCompress (itemUrl) {
return new Promise((resolve, reject)=>{
uni.getFileInfo({
filePath: itemUrl,
success: (res) => {
console.log('压缩之前图片大小----',res) //返回图片尺寸
resolve(res)
},
fail: (err) =>{
reject(err)
}
})
})
},
//h5
recursionCompressH5(url, callback) {
if (typeof url === 'string') {
this.getUserImageCompressH5(url,callback)
} else if (typeof url === 'object') {
for (let itemImg of url) {
this.getUserImageCompressH5(itemImg,callback)
}
}
},
ヒント: H5 側の Canvas に描画された画像が正常に動作するには、クロスドメイン アクセスをサポートする必要があるためです。そのため、 h5 側のuni.canvasToTempFilePath は空を返すため、画像情報を取得するには、toBlob を使用してファイルに変換し、次にcreateObjectURLを使用して URL に変換する必要があります。圧縮率を制御します。
// h5压缩图片
getUserImageCompressH5 (imgUrl,callback) {
let that = this;
return new Promise((resolve, reject)=>{
uni.getImageInfo({
src: imgUrl,
success(res) {
let canvasWidth = res.width; //图片原始长宽
let canvasHeight = res.height;
let img = new Image();
img.src = res.path;
console.log(5435435353)
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = canvasWidth / 2;
canvas.height = canvasHeight / 2;
ctx.drawImage(img, 0, 0, canvasWidth / 2, canvasHeight / 2);
canvas.toBlob(function(fileSrc) {
let imgSrc = window.URL.createObjectURL(fileSrc);
uni.getFileInfo({
filePath: imgSrc,
success: (resFileInfo) => {
if (resFileInfo.size > 150000) {
//压缩后大于1M就继续压缩
that.recursionCompressH5(imgSrc, callback);
return;
} else {
callback && callback(imgSrc)
resolve(imgSrc)
that.tempImageList.push(imgSrc)
}
},
});
});
}
});
})
},
2. 画像を削除する
delete 関数は非常に簡単で、配列側の delete メソッドを直接使用するだけですsplice
。
deleteSelectImg(index) {
this.tempImageList.splice(index, 1)
},
3. レンダリング
ページの UI 構造については、ここには貼り付けません。実際のニーズに応じて実装できます。
問題があります
圧縮率の制御にはまだいくつかの欠陥があり、指定されたサイズの画像を圧縮するという問題を完全には解決できません。
ご不明な点がございましたら、ご指摘ください。...