diff --git a/library/src/main/ets/components/imageknife/utils/PixelUtils.ets b/library/src/main/ets/components/imageknife/utils/PixelUtils.ets index ce61142..f664463 100644 --- a/library/src/main/ets/components/imageknife/utils/PixelUtils.ets +++ b/library/src/main/ets/components/imageknife/utils/PixelUtils.ets @@ -13,20 +13,20 @@ * limitations under the License. */ -import {CalculatePixelUtils} from "./CalculatePixelUtils" -import {PixelEntry} from "../entry/PixelEntry" -import {AsyncTransform} from "../transform/AsyncTransform" -import {ColorUtils} from "./ColorUtils" -import {Size} from "../../imageknife/RequestOption" -import {GPUImagePixelationFilter} from '@ohos/gpu_transform' +import { CalculatePixelUtils } from "./CalculatePixelUtils" +import { PixelEntry } from "../entry/PixelEntry" +import { AsyncTransform } from "../transform/AsyncTransform" +import { ColorUtils } from "./ColorUtils" +import { Size } from "../../imageknife/RequestOption" +import { GPUImagePixelationFilter } from '@ohos/gpu_transform' import image from '@ohos.multimedia.image'; export namespace pixelUtils { export async function pixel(bitmap: PixelMap, pixel: number, func?: AsyncTransform) { - let imageInfo:image.ImageInfo= await bitmap.getImageInfo(); - let size:Size = { + let imageInfo: image.ImageInfo = await bitmap.getImageInfo(); + let size: Size = { width: imageInfo.size.width, height: imageInfo.size.height } @@ -34,43 +34,14 @@ export namespace pixelUtils { func?.asyncTransform("GrayscaleTransformation The image size does not exist.", null) return; } - let targetWidth:number = size.width; - let targetHeight:number = size.height; - let pixEntry: Array = new Array() - let inPixels: Array> = CalculatePixelUtils.createInt2DArray(targetHeight, targetWidth); + let targetWidth: number = size.width; + let targetHeight: number = size.height; let bufferData = new ArrayBuffer(bitmap.getPixelBytesNumber()); await bitmap.readPixelsToBuffer(bufferData); let dataArray = new Uint8Array(bufferData); - let ph:number = 0; - let pw:number = 0; - - - for (let index = 0; index < dataArray.length; index += 4) { - const r = dataArray[index]; - const g = dataArray[index+1]; - const b = dataArray[index+2]; - const f = dataArray[index+3]; - - let entry = new PixelEntry(); - entry.a = 0; - entry.b = b; - entry.g = g; - entry.r = r; - entry.f = f; - entry.pixel = ColorUtils.rgb(entry.r, entry.g, entry.b); - pixEntry.push(entry); - inPixels[ph][pw] = ColorUtils.rgb(entry.r, entry.g, entry.b); - if (pw == targetWidth - 1) { - pw = 0; - ph++; - } else { - pw++; - } - } - let realPixel_W = pixel > targetWidth ? targetWidth : pixel; let realPixel_H = pixel > targetHeight ? targetHeight : pixel; @@ -78,54 +49,54 @@ export namespace pixelUtils { let x_index = Math.floor(targetWidth / realPixel_W); // 纵排的正方形个数 let y_index = Math.floor(targetHeight / realPixel_H); + let inPixels: Array> = CalculatePixelUtils.createInt2DArray(y_index, x_index) + // 每个马赛克块左上角的像素在图片一维数组中对应的索引位置 + let startIndex = 0 + // 像素步进数 + const PIXEL_STEP = 4 + // 图片马赛克化之后,一行马赛克所包含的像素数 + const mosaicRowPixels = targetWidth * pixel * PIXEL_STEP for (let ch = 0; ch < y_index; ch++) { for (let cw = 0; cw < x_index; cw++) { - - let max_x = (cw + 1) * realPixel_W > targetWidth ? targetWidth : (cw + 1) * realPixel_W; - let max_y = (ch + 1) * realPixel_H > targetHeight ? targetHeight : (ch + 1) * realPixel_H; - - - let min_x = cw * realPixel_W; - let min_y = ch * realPixel_H; - - // 取左上角的像素值 - let center_p = inPixels[min_y+1][min_x+1]; - // 设置该正方形里的像素统一 - for (let zh = min_y; zh < max_y; zh++) { - for (let zw = min_x; zw < max_x; zw++) { - inPixels[zh][zw] = center_p; - } - } + startIndex = mosaicRowPixels * ch + cw * pixel * PIXEL_STEP + const r = dataArray[startIndex] + const g = dataArray[startIndex+1]; + const b = dataArray[startIndex+2]; + const f = dataArray[startIndex+3]; + let entry = new PixelEntry(); + entry.a = 0; + entry.b = b; + entry.g = g; + entry.r = r; + entry.f = f; + inPixels[ch][cw] = ColorUtils.rgb(entry.r, entry.g, entry.b); } } - let bufferNewData = new ArrayBuffer(bitmap.getPixelBytesNumber()); let dataNewArray = new Uint8Array(bufferNewData); - let index = 0; - let mh = 0; - let nw = 0; - for (let i = 0; i < dataNewArray.length; i += 4) { - let pixel_1 = inPixels[mh][nw]; + for (let i = 0; i < dataNewArray.length; i += PIXEL_STEP) { + // 像素在二维数组中纵轴方向上的索引 + let y = Math.floor(i / targetHeight / PIXEL_STEP) + // 像素在二维数组中横轴方向上的索引 + let x = Math.floor((i - (y * targetHeight * PIXEL_STEP)) / PIXEL_STEP) - if (nw == targetWidth - 1) { - nw = 0; - mh++; - } else { - nw++; - } + // 对应马赛克块二维数组的位置 + y = Math.floor(y / pixel) + x = Math.floor(x / pixel) - let p_r = ColorUtils.red(pixel_1); - let p_g = ColorUtils.green(pixel_1); - let p_b = ColorUtils.blue(pixel_1); + // 未被马赛克覆盖的部分,用最近的色块颜色覆盖 + y = y >= y_index ? y_index - 1 : y + x = x >= x_index ? x_index - 1 : x - dataNewArray[i] = p_r; - dataNewArray[i+1] = p_g; - dataNewArray[i+2] = p_b; - dataNewArray[i+3] = pixEntry[index].f; - index++; + const color = inPixels[y][x] + + dataNewArray[i] = ColorUtils.red(color); + dataNewArray[i+1] = ColorUtils.green(color); + dataNewArray[i+2] = ColorUtils.blue(color); + dataNewArray[i+3] = ColorUtils.alpha(color) } await bitmap.writeBufferToPixels(bufferNewData); if (func) { @@ -134,8 +105,8 @@ export namespace pixelUtils { } export async function pixelGPU(bitmap: PixelMap, pixel: number, func?: AsyncTransform) { - let imageInfo:image.ImageInfo = await bitmap.getImageInfo(); - let size:Size = { + let imageInfo: image.ImageInfo = await bitmap.getImageInfo(); + let size: Size = { width: imageInfo.size.width, height: imageInfo.size.height } @@ -153,7 +124,7 @@ export namespace pixelUtils { filter.setPixel(pixel) filter.getPixelMapBuf(0, 0, w, h).then((buf) => { bitmap.writeBufferToPixels(buf); - if (func!=undefined) { + if (func != undefined) { func?.asyncTransform("success", bitmap); } })