100aff185Sopenharmony_ci/* 200aff185Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 300aff185Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 400aff185Sopenharmony_ci * you may not use this file except in compliance with the License. 500aff185Sopenharmony_ci * You may obtain a copy of the License at 600aff185Sopenharmony_ci * 700aff185Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 800aff185Sopenharmony_ci * 900aff185Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1000aff185Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1100aff185Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1200aff185Sopenharmony_ci * See the License for the specific language governing permissions and 1300aff185Sopenharmony_ci * limitations under the License. 1400aff185Sopenharmony_ci */ 1500aff185Sopenharmony_ci 1600aff185Sopenharmony_ciimport { Log } from './Log'; 1700aff185Sopenharmony_ciimport { Constants } from '../model/common/Constants'; 1800aff185Sopenharmony_ciimport display from '@ohos.display'; 1900aff185Sopenharmony_ciimport image from '@ohos.multimedia.image'; 2000aff185Sopenharmony_ci 2100aff185Sopenharmony_ciconst TAG: string = 'common_ImageUtil'; 2200aff185Sopenharmony_ci 2300aff185Sopenharmony_citype ImageSize = { 2400aff185Sopenharmony_ci width: number; 2500aff185Sopenharmony_ci height: number; 2600aff185Sopenharmony_ci}; 2700aff185Sopenharmony_ci 2800aff185Sopenharmony_ciexport class ImageUtil { 2900aff185Sopenharmony_ci // 默认缩略图大小,用于大图跳转 3000aff185Sopenharmony_ci static readonly DEFAULT_THUMBNAIL_SIZE: number = 640; 3100aff185Sopenharmony_ci 3200aff185Sopenharmony_ci static computeSampleSize(width: number, height: number, minSideLength: number, maxNumOfPixels: number): number { 3300aff185Sopenharmony_ci if (width == 0 || height == 0 || minSideLength == 0 || maxNumOfPixels == 0) { 3400aff185Sopenharmony_ci return 2; 3500aff185Sopenharmony_ci } 3600aff185Sopenharmony_ci let initialSize = ImageUtil.computeInitialSampleSize(width, height, minSideLength, maxNumOfPixels); 3700aff185Sopenharmony_ci Log.debug(TAG, `initialSize: ${initialSize}`); 3800aff185Sopenharmony_ci return initialSize <= 8 ? ImageUtil.nextPowerOf2(initialSize) : Math.floor((initialSize + 8 - 1) / 8) * 8; 3900aff185Sopenharmony_ci } 4000aff185Sopenharmony_ci 4100aff185Sopenharmony_ci static getScreenNailSize(size: image.Size): void { 4200aff185Sopenharmony_ci let displayClass: display.Display = display.getDefaultDisplaySync(); 4300aff185Sopenharmony_ci // 屏幕最长边px值 4400aff185Sopenharmony_ci let screenWidth: number = displayClass.width; 4500aff185Sopenharmony_ci let screenHeight: number = displayClass.height; 4600aff185Sopenharmony_ci let maxScreenSideLength = Math.max(screenWidth, screenHeight); 4700aff185Sopenharmony_ci Log.info(TAG, `getScreenNailSize maxSideLength: ${maxScreenSideLength}`); 4800aff185Sopenharmony_ci let targetSize = maxScreenSideLength * Constants.NUMBER_1 / Constants.NUMBER_4; 4900aff185Sopenharmony_ci let sizeWidth: number = size.width; 5000aff185Sopenharmony_ci let sizeHeight: number = size.height; 5100aff185Sopenharmony_ci let maxImageSideLength: number = Math.max(sizeWidth, sizeHeight); 5200aff185Sopenharmony_ci if (maxImageSideLength === 0) { 5300aff185Sopenharmony_ci Log.error(TAG, 'screen max length is zero'); 5400aff185Sopenharmony_ci return; 5500aff185Sopenharmony_ci } 5600aff185Sopenharmony_ci let scale = targetSize / maxImageSideLength; 5700aff185Sopenharmony_ci size.width = Math.ceil(size.width * scale); 5800aff185Sopenharmony_ci size.height = Math.ceil(size.height * scale); 5900aff185Sopenharmony_ci Log.info(TAG, `getScreenNailSize scale: ${scale}, target height ${size.height}`); 6000aff185Sopenharmony_ci } 6100aff185Sopenharmony_ci 6200aff185Sopenharmony_ci static nextPowerOf2(value: number): number { 6300aff185Sopenharmony_ci let useValue = value; 6400aff185Sopenharmony_ci if (useValue <= 0 || useValue > (1 << 30)) { 6500aff185Sopenharmony_ci Log.warn(TAG, `invalid sample value ${useValue}!`); 6600aff185Sopenharmony_ci return 1; 6700aff185Sopenharmony_ci } 6800aff185Sopenharmony_ci useValue -= 1; 6900aff185Sopenharmony_ci useValue |= useValue >> 16; 7000aff185Sopenharmony_ci useValue |= useValue >> 8; 7100aff185Sopenharmony_ci useValue |= useValue >> 4; 7200aff185Sopenharmony_ci useValue |= useValue >> 2; 7300aff185Sopenharmony_ci useValue |= useValue >> 1; 7400aff185Sopenharmony_ci Log.debug(TAG, `nextPowerOf2:${useValue}`); 7500aff185Sopenharmony_ci return useValue + 1; 7600aff185Sopenharmony_ci } 7700aff185Sopenharmony_ci 7800aff185Sopenharmony_ci /** 7900aff185Sopenharmony_ci * Calculate the aspect ratio, considering the direction of rotation 8000aff185Sopenharmony_ci * 8100aff185Sopenharmony_ci * @param info include orientation width height 8200aff185Sopenharmony_ci * @return the aspect ratio 8300aff185Sopenharmony_ci */ 8400aff185Sopenharmony_ci static calcRatio(info: ImageSize): number { 8500aff185Sopenharmony_ci if (info == null || info == undefined) { 8600aff185Sopenharmony_ci return 1; 8700aff185Sopenharmony_ci } 8800aff185Sopenharmony_ci if (info.width == 0 || info.height == 0) { 8900aff185Sopenharmony_ci return 1; 9000aff185Sopenharmony_ci } 9100aff185Sopenharmony_ci return info.width / info.height; 9200aff185Sopenharmony_ci } 9300aff185Sopenharmony_ci 9400aff185Sopenharmony_ci /** 9500aff185Sopenharmony_ci * 计算缩略图大小生成对应路径 9600aff185Sopenharmony_ci * 计算缩略图大小规格:短边等于不小于给定大小;如果原图短边小于给定大小则返回原图大小 9700aff185Sopenharmony_ci * 9800aff185Sopenharmony_ci * @param uri 图片媒体路径 9900aff185Sopenharmony_ci * @param imageHeight 图片原高 10000aff185Sopenharmony_ci * @param imageWidth 图片原宽 10100aff185Sopenharmony_ci */ 10200aff185Sopenharmony_ci static calcThumbnail(uri: string, imageHeight: number, imageWidth: number, orientation?: number): string { 10300aff185Sopenharmony_ci if (uri == null) { 10400aff185Sopenharmony_ci return ''; 10500aff185Sopenharmony_ci } 10600aff185Sopenharmony_ci if (!imageWidth || !imageHeight) { 10700aff185Sopenharmony_ci // 长宽无效返回缩略图默认值256 * 256 10800aff185Sopenharmony_ci return `${uri}/thumbnail/256/256` 10900aff185Sopenharmony_ci } 11000aff185Sopenharmony_ci if (imageHeight < this.DEFAULT_THUMBNAIL_SIZE || imageWidth < this.DEFAULT_THUMBNAIL_SIZE) { 11100aff185Sopenharmony_ci return `${uri}/thumbnail/${imageWidth}/${imageHeight}` 11200aff185Sopenharmony_ci } 11300aff185Sopenharmony_ci 11400aff185Sopenharmony_ci let width = 0; 11500aff185Sopenharmony_ci let height = 0; 11600aff185Sopenharmony_ci if (orientation != null && (orientation == Constants.ANGLE_90 || orientation == Constants.ANGLE_270)) { 11700aff185Sopenharmony_ci let temp = imageWidth; 11800aff185Sopenharmony_ci imageWidth = imageHeight; 11900aff185Sopenharmony_ci imageHeight = temp; 12000aff185Sopenharmony_ci } 12100aff185Sopenharmony_ci if (imageHeight < imageWidth) { 12200aff185Sopenharmony_ci height = this.DEFAULT_THUMBNAIL_SIZE; 12300aff185Sopenharmony_ci width = Math.round(height * imageWidth / imageHeight) 12400aff185Sopenharmony_ci } else { 12500aff185Sopenharmony_ci width = this.DEFAULT_THUMBNAIL_SIZE; 12600aff185Sopenharmony_ci height = Math.round(width * imageHeight / imageWidth); 12700aff185Sopenharmony_ci } 12800aff185Sopenharmony_ci return `${uri}/thumbnail/${width}/${height}` 12900aff185Sopenharmony_ci } 13000aff185Sopenharmony_ci 13100aff185Sopenharmony_ci private static computeInitialSampleSize(width: number, height: number, 13200aff185Sopenharmony_ci minSideLength: number, maxNumOfPixels: number): number { 13300aff185Sopenharmony_ci if ((maxNumOfPixels == -1) && (minSideLength == -1)) { 13400aff185Sopenharmony_ci return 1; 13500aff185Sopenharmony_ci } 13600aff185Sopenharmony_ci 13700aff185Sopenharmony_ci let lowerBound: number = (maxNumOfPixels == -1) ? 1 : Math.ceil(Math.sqrt((width * height) / maxNumOfPixels)); 13800aff185Sopenharmony_ci Log.debug(TAG, `lowerBound: ${lowerBound}`); 13900aff185Sopenharmony_ci if (minSideLength == -1) { 14000aff185Sopenharmony_ci return lowerBound; 14100aff185Sopenharmony_ci } else { 14200aff185Sopenharmony_ci let sampleSize = Math.min(width / minSideLength, height / minSideLength); 14300aff185Sopenharmony_ci return Math.max(sampleSize, lowerBound); 14400aff185Sopenharmony_ci } 14500aff185Sopenharmony_ci } 14600aff185Sopenharmony_ci}