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 */ 15 16import type { MediaItem, Size } from '@ohos/common'; 17import { BrowserDataFactory, ImageUtil, Log, ScreenManager } from '@ohos/common'; 18import { PixelMapWrapper } from './base/PixelMapWrapper'; 19import { CropAngle } from './crop/CropType'; 20import userFileManager from '@ohos.filemanagement.userFileManager'; 21 22const TAG: string = 'editor_Loader'; 23 24export class Loader { 25 private static readonly MIN_PIXEL_MAP_SIZE: number = 1024; 26 27 static async loadPixelMapWrapper(mediaItem: MediaItem, isPreview: boolean = false): Promise<PixelMapWrapper> { 28 Log.debug(TAG, `Photo: loadPixelMap uri = ${mediaItem.uri}`); 29 let dataImpl = BrowserDataFactory.getFeature(BrowserDataFactory.TYPE_PHOTO); 30 31 let result = await dataImpl.getDataByUri(mediaItem.uri); 32 if (!result) { 33 Log.error(TAG, 'get file asset failed.'); 34 return null; 35 } 36 37 Log.error(TAG, 'get file asset failed.'); 38 39 let size = { 40 width: result.get(userFileManager.ImageVideoKey.WIDTH.toString()) as number, 41 height: result.get(userFileManager.ImageVideoKey.HEIGHT.toString()) as number 42 }; 43 44 isPreview && Loader.getPixelMapPreviewSize(size); 45 46 let thumbnail = await result.getThumbnail(size); 47 let wrapper = new PixelMapWrapper(thumbnail, px2vp(size.width), px2vp(size.height)); 48 Log.info(TAG, `Photo: loadPixelMap: size[${JSON.stringify(size)}] wrapper[${JSON.stringify(wrapper)}]`); 49 50 let orientation = mediaItem.orientation || 0; 51 Loader.translatePixelMap(wrapper, orientation); 52 Log.info(TAG, `Photo: loadPixelMap: final wrapper[${JSON.stringify(wrapper)}]`); 53 return wrapper; 54 } 55 56 private static getPixelMapPreviewSize(size: Size) { 57 let width = ScreenManager.getInstance().getWinWidth(); 58 let height = ScreenManager.getInstance().getWinHeight(); 59 Log.debug(TAG, `picture real size: ${size.width} ${size.height}`); 60 let scale = ImageUtil.computeSampleSize(size.width, size.height, Loader.MIN_PIXEL_MAP_SIZE, width * height * 2); 61 size.width = Math.ceil(size.width / scale); 62 size.height = Math.ceil(size.height / scale); 63 Log.debug(TAG, `picture scale: ${scale} size: ${JSON.stringify(size)}`); 64 } 65 66 private static translatePixelMap(image: PixelMapWrapper, orientation: number) { 67 if (0 == orientation % CropAngle.CIRCLE_ANGLE) { 68 return image; 69 } 70 71 let size = Loader.swapSize(image, orientation); 72 let offWidth = size.width; 73 let offHeight = size.height; 74 let setting = new RenderingContextSettings(true) 75 let context = new OffscreenCanvasRenderingContext2D(offWidth, offHeight, setting); 76 77 context.save(); 78 context.drawImage(image.pixelMap, 0, 0, offWidth, offHeight); 79 context.restore(); 80 81 image.pixelMap && image.pixelMap.release(); 82 image.pixelMap = context.getPixelMap(0, 0, offWidth, offHeight); 83 image.width = size.width; 84 image.height = size.height; 85 } 86 87 private static swapSize(image: PixelMapWrapper, orientation: number): Size { 88 let angle = orientation % CropAngle.HALF_CIRCLE_ANGLE; 89 let size = { 90 width: image.width, 91 height: image.height 92 }; 93 if (0 != angle) { 94 size.width = image.height; 95 size.height = image.width; 96 } 97 return size; 98 } 99}