• 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 */
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}