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 { Log } from '@ohos/common'; 17import { RectF } from '../base/Rect'; 18import { ImageFilterBase } from '../base/ImageFilterBase'; 19import { PixelMapWrapper } from '../base/PixelMapWrapper'; 20import { MathUtils } from './MathUtils'; 21 22const TAG: string = 'editor_ImageFilterCrop'; 23 24export class ImageFilterCrop extends ImageFilterBase { 25 private static readonly FILTER_NAME: string = 'FilterCrop'; 26 private isFlipHorizontal: boolean = false; 27 private isFlipVertically: boolean = false; 28 private rotationAngle: number = 0; 29 private horizontalAngle: number = 0; 30 private cropRect: RectF = undefined; 31 32 constructor() { 33 super(ImageFilterCrop.FILTER_NAME); 34 this.cropRect = new RectF(); 35 } 36 37 render(pixelMap: PixelMapWrapper): PixelMapWrapper { 38 Log.debug(TAG, `render input wrapper: ${JSON.stringify(pixelMap)}`); 39 let width = pixelMap.width; 40 let height = pixelMap.height; 41 let realCropRect = new RectF(); 42 realCropRect.set(this.cropRect.left, this.cropRect.top, this.cropRect.right, this.cropRect.bottom); 43 MathUtils.revertRect(realCropRect, width, height); 44 45 let offWidth = realCropRect.getWidth(); 46 let offHeight = realCropRect.getHeight(); 47 let setting = new RenderingContextSettings(true); 48 let offCtx = new OffscreenCanvasRenderingContext2D(offWidth, offHeight, setting); 49 let tX = this.isFlipHorizontal ? -1 : 1; 50 let tY = this.isFlipVertically ? -1 : 1; 51 52 offCtx.save(); 53 offCtx.translate(this.isFlipHorizontal ? offWidth : 0, this.isFlipVertically ? offHeight : 0); 54 offCtx.scale(tX, tY); 55 56 offCtx.translate(offWidth / 2, offHeight / 2); 57 offCtx.rotate(MathUtils.formulaAngle(this.rotationAngle * tX * tY + this.horizontalAngle)); 58 offCtx.translate(-offWidth / 2, -offHeight / 2); 59 offCtx.translate(-realCropRect.left, -realCropRect.top); 60 61 offCtx.drawImage(pixelMap.pixelMap, 0, 0, width, height); 62 offCtx.restore(); 63 let outputPixelMap = offCtx.getPixelMap(0, 0, offWidth, offHeight); 64 let output = new PixelMapWrapper(outputPixelMap, offWidth, offHeight); 65 Log.debug(TAG, `render output wrapper: ${JSON.stringify(output)}`); 66 return output; 67 } 68 69 setFlipHorizontal(isFlip: boolean) { 70 this.isFlipHorizontal = isFlip; 71 } 72 73 setFlipVertically(isFlip: boolean) { 74 this.isFlipVertically = isFlip; 75 } 76 77 setRotationAngle(angle: number) { 78 this.rotationAngle = angle; 79 } 80 81 setHorizontalAngle(angle: number) { 82 this.horizontalAngle = angle; 83 } 84 85 setCropRect(rect: RectF) { 86 this.cropRect.set(rect.left, rect.top, rect.right, rect.bottom); 87 } 88}