1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import MediaLib from '@ohos.multimedia.mediaLibrary'; 16import { Log } from '@ohos/base/src/main/ets/utils/Log'; 17import { MediaDataItem } from '@ohos/base/src/main/ets/data/MediaDataItem'; 18import type { Size } from '../../common/model/common/DataTypes'; 19import { PixelMapWrapper } from './base/PixelMapWrapper'; 20import { MathUtils } from './crop/MathUtils'; 21import { CropAngle } from './crop/CropType'; 22import { computeSampleSize } from '@ohos/base/src/main/ets/utils/ImageUtil'; 23import screenManager from '@ohos/base/src/main/ets/manager/ScreenManager'; 24 25const TAG = "Loader" 26 27export class Loader { 28 private static readonly MIN_PIXEL_MAP_SIZE: number = 1024; 29 30 private static getPixelMapPreviewSize(size: Size) { 31 let width = screenManager.getWinWidth(); 32 let height = screenManager.getWinHeight(); 33 Log.debug(TAG, `picture real size: ${size.width} ${size.height}`); 34 let scale = computeSampleSize(size.width, size.height, Loader.MIN_PIXEL_MAP_SIZE, width * height * 2); 35 size.width = Math.ceil(size.width / scale); 36 size.height = Math.ceil(size.height / scale); 37 Log.debug(TAG, `picture scale: ${scale} size: ${JSON.stringify(size)}`); 38 } 39 40 static async loadPixelMapWrapper(mediaItem: MediaDataItem, isPreview: boolean = false): Promise<PixelMapWrapper> { 41 Log.debug(TAG, `Photo: loadPixelMap id = ${mediaItem.id}`); 42 let fileAsset: MediaLib.FileAsset = await mediaItem.loadFileAsset() 43 let size = { 44 width: fileAsset.width, 45 height: fileAsset.height 46 }; 47 isPreview && Loader.getPixelMapPreviewSize(size); 48 49 let thumbnail = await fileAsset.getThumbnail(size); 50 let wrapper = new PixelMapWrapper(thumbnail, px2vp(size.width), px2vp(size.height)); 51 Log.info(TAG, `Photo: loadPixelMap: size[${JSON.stringify(size)}] wrapper[${JSON.stringify(wrapper)}]`); 52 53 let orientation = mediaItem.orientation || 0; 54 await Loader.translatePixelMap(wrapper, orientation); 55 Log.info(TAG, `Photo: loadPixelMap: final wrapper[${JSON.stringify(wrapper)}]`); 56 return wrapper; 57 } 58 59 private static translatePixelMap(image: PixelMapWrapper, orientation: number) { 60 if (0 == orientation % CropAngle.CIRCLE_ANGLE) { 61 return image; 62 } 63 64 let size = Loader.swapSize(image, orientation); 65 let offWidth = size.width; 66 let offHeight = size.height; 67 let setting = new RenderingContextSettings(true) 68 let context = new OffscreenCanvasRenderingContext2D(offWidth, offHeight, setting); 69 70 context.save(); 71 context.drawImage(image.pixelMap, 0, 0, offWidth, offHeight); 72 context.restore(); 73 74 image.pixelMap && image.pixelMap.release(); 75 image.pixelMap = context.getPixelMap(0, 0, offWidth, offHeight); 76 image.width = size.width; 77 image.height = size.height; 78 } 79 80 private static swapSize(image: PixelMapWrapper, orientation: number): Size { 81 let angle = orientation % CropAngle.HALF_CIRCLE_ANGLE; 82 let size = { 83 width: image.width, 84 height: image.height 85 }; 86 if (0 != angle) { 87 size.width = image.height; 88 size.height = image.width; 89 } 90 return size; 91 } 92}