1. 相册选择图片
static getPhoto(callback?: (result: string) => void) {
try {
let photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = 1;
let photoPicker = new picker.PhotoViewPicker();
photoPicker.select(photoSelectOptions).then((photoSelectResult: picker.PhotoSelectResult) => {
QDLogUtils.debug('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(photoSelectResult));
let arr = photoSelectResult['photoUris']
let uri = arr[0]
try {
let file: fileIo.File = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
let buffer = new ArrayBuffer(1024 * 1024 * 10);
let fileFd = file.fd
let readLen = fileIo.readSync(fileFd, buffer);
buffer = buffer.slice(0, readLen)
fileIo.closeSync(fileFd);
QDImageCompressionUtils.imageCompression(buffer, (res) => {
let content = QDStringUtils.base64Encode(new Uint8Array(res))
if (callback) callback(content)
})
} catch (err) {
QDLogUtils.error(`photoPicker.select err = ${err}`)
if (callback) callback("")
}
}).catch((err: BusinessError) => {
QDLogUtils.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
if (callback) callback("")
});
} catch (error) {
let err: BusinessError = error as BusinessError;
QDLogUtils.error('PhotoViewPicker failed with err: ' + JSON.stringify(err));
if (callback) callback("")
}
}
1. 图片压缩 QDImageCompressionUtils
import { BusinessError } from '@ohos.base';
import fs from '@ohos.file.fs';
import image from '@ohos.multimedia.image';
import QDLogUtils from './QDLogUtils';
class QDImageCompressionUtils {
imageCompression(buffer: ArrayBuffer, callback: (buffer: ArrayBuffer) => void, maxCompressedImageSize: number = 100): void {
const imageSource: image.ImageSource = image.createImageSource(buffer);
let decodingOptions: image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3,
}
imageSource.createPixelMap(decodingOptions).then((originalPixelMap: image.PixelMap) => {
this.compressedImage(originalPixelMap, maxCompressedImageSize).then((buffer: ArrayBuffer) => {
if (callback) {
callback(buffer)
}
})
}).catch((err: BusinessError) => {
QDLogUtils.error(`Failed to create PixelMap with error message: ${err.message}, error code: ${err.code}`);
});
}
private async compressedImage(sourcePixelMap: PixelMap, maxCompressedImageSize: number): Promise<ArrayBuffer> {
let imagePackerApi = image.createImagePacker();
let imageQuality = 0;
let packOpts: image.PackingOption = { format: "image/jpeg", quality: imageQuality };
let compressedImageData: ArrayBuffer = await imagePackerApi.packing(sourcePixelMap, packOpts);
let maxCompressedImageByte = maxCompressedImageSize * 1024;
if (maxCompressedImageByte > compressedImageData.byteLength) {
compressedImageData = await this.packingImage(compressedImageData, sourcePixelMap, imageQuality, maxCompressedImageByte);
} else {
let imageScale = 1;
let reduceScale = 0.4;
while (compressedImageData.byteLength > maxCompressedImageByte) {
if (imageScale > 0) {
imageScale = imageScale - reduceScale;
await sourcePixelMap.scale(imageScale, imageScale);
compressedImageData = await this.packing(sourcePixelMap, imageQuality);
} else {
break;
}
}
}
return compressedImageData
}
private async packing(sourcePixelMap: PixelMap, imageQuality: number): Promise<ArrayBuffer> {
let imagePackerApi = image.createImagePacker();
let packOpts: image.PackingOption = { format: "image/jpeg", quality: imageQuality };
let data: ArrayBuffer = await imagePackerApi.packing(sourcePixelMap, packOpts);
return data;
}
private async packingImage(compressedImageData: ArrayBuffer, sourcePixelMap: PixelMap, imageQuality: number, maxCompressedImageByte: number): Promise<ArrayBuffer> {
let packingArray: number[] = [];
let dichotomyAccuracy = 10;
for (let i = 0; i <= 100; i += dichotomyAccuracy) {
packingArray.push(i);
}
let left = 0;
let right = packingArray.length - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
imageQuality = packingArray[mid];
compressedImageData = await this.packing(sourcePixelMap, imageQuality);
if (compressedImageData.byteLength <= maxCompressedImageByte) {
left = mid + 1;
if (mid === packingArray.length - 1) {
break;
}
compressedImageData = await this.packing(sourcePixelMap, packingArray[mid + 1]);
if (compressedImageData.byteLength > maxCompressedImageByte) {
compressedImageData = await this.packing(sourcePixelMap, packingArray[mid]);
break;
}
} else {
right = mid - 1;
}
}
return compressedImageData;
}
private async saveImage(compressedImageData: ArrayBuffer): Promise<CompressedImageInfo> {
let context: Context = getContext();
let compressedImageUri: string = context.filesDir + '/' + 'afterCompressiona.jpeg';
try {
let res = fs.accessSync(compressedImageUri);
if (res) {
fs.unlinkSync(compressedImageUri);
}
} catch (err) {
QDLogUtils.error(`AccessSync failed with error message: ${err.message}, error code: ${err.code}`);
}
let file: fs.File = fs.openSync(compressedImageUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file.fd, compressedImageData);
fs.closeSync(file);
let compressedImageInfo: CompressedImageInfo = new CompressedImageInfo();
compressedImageInfo.imageUri = compressedImageUri;
compressedImageInfo.imageByteLength = compressedImageData.byteLength;
return compressedImageInfo;
}
}
export default new QDImageCompressionUtils()
class CompressedImageInfo {
imageUri: string = "";
imageByteLength: number = 0;
}