import { Group, Panel, jsx, Color, layoutConfig, Image, Scroller, VLayout, Text, Gravity, createRef, loge, ViewComponent, HLayout, Stack, GestureContainer, } from "doric"; import { binarization, extractGrayValue, fastBlur, gaussianBlur, ostu, pixelToRGBA, vampix, } from "./imageUtils"; import { colors } from "./utils"; @ViewComponent export class Label extends Text { constructor() { super(); this.width = 100; this.height = 40; this.backgroundColor = colors[1]; this.textColor = Color.WHITE; this.textSize = 20; } } @Entry export class ImageProcessorDemo extends Panel { build(root: Group): void { const iv = createRef(); const imageUrl = "https://doric.pub/about/The_Parthenon_in_Athens.jpg"; let imageInfo: { width: number; height: number }; let pixels: ArrayBuffer; 图片处理 { imageInfo = await iv.current.getImageInfo(context); pixels = (await iv.current.getImagePixels(context)).slice(0); }} /> 透明度 {(() => { const spinnerRef = createRef(); const containerRef = createRef(); this.addOnRenderFinishedCallback(async () => { async function changeAlpha(alpha: number) { const data = new Uint8Array(pixels); for (let i = 0; i < data.length - 4; i += 4) { data[i + 3] = alpha; } iv.current.imagePixels = { width: imageInfo.width, height: imageInfo.height, pixels: pixels, }; } const width = await containerRef.current.getWidth(this.context); containerRef.current.onTouchDown = async (event) => { spinnerRef.current.width = event.x; await changeAlpha((1 - event.x / width) * 0xff); }; containerRef.current.onTouchMove = async (event) => { spinnerRef.current.width = event.x; await changeAlpha((1 - event.x / width) * 0xff); }; }); return ( ); })()} 二值化 {(() => { const spinnerRef = createRef(); const containerRef = createRef(); this.addOnRenderFinishedCallback(async () => { let data: Uint32Array | undefined = undefined; async function binarizationImage(t: number) { if (!!!data) { data = new Uint32Array(pixels); for (let i = 0; i < data.length; i++) { let { r, g, b } = pixelToRGBA(data[i]); data[i] = Math.floor(r * 0.2989 + g * 0.587 + b * 0.114); } } const arrayBuffer = pixels.slice(0); const ret = new Uint32Array(arrayBuffer); for (let i = 0; i < data.length; i++) { ret[i] = data[i] < t ? 0xff000000 : 0xffffffff; } iv.current.setImagePixels(context, { width: imageInfo.width, height: imageInfo.height, pixels: arrayBuffer, }); iv.current.imagePixels = { width: imageInfo.width, height: imageInfo.height, pixels: arrayBuffer, }; } const width = await containerRef.current.getWidth(this.context); containerRef.current.onTouchDown = async (event) => { spinnerRef.current.width = event.x; await binarizationImage((1 - event.x / width) * 0xff); }; containerRef.current.onTouchMove = async (event) => { spinnerRef.current.width = event.x; await binarizationImage((1 - event.x / width) * 0xff); }; }); return ( ); })()} 模糊 {(() => { const spinnerRef = createRef(); const containerRef = createRef(); this.addOnRenderFinishedCallback(async () => { async function blurEffect(radius: number) { radius = Math.round(radius); const buffer = pixels.slice(0); const data = new Uint32Array(buffer); fastBlur(data, imageInfo.width, imageInfo.height, radius); iv.current.imagePixels = { width: imageInfo.width, height: imageInfo.height, pixels: buffer, }; } const width = await containerRef.current.getWidth(this.context); containerRef.current.onTouchDown = async (event) => { spinnerRef.current.width = event.x; await blurEffect((event.x / width) * 100); }; containerRef.current.onTouchMove = async (event) => { spinnerRef.current.width = event.x; await blurEffect((event.x / width) * 100); }; }); return ( ); })()} 简单 模糊 二值化 ; } }