• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}