缩短非GPU加速下图片马赛克处理近3倍时间

Signed-off-by: Bo Lan <mai925093@gmail.com>
This commit is contained in:
Bo Lan 2024-04-08 14:19:48 +08:00
parent 4d5728dc3a
commit 6cc1d077d6
1 changed files with 49 additions and 78 deletions

View File

@ -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<PixelMap>) {
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<PixelEntry> = new Array()
let inPixels: Array<Array<number>> = 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<Array<number>> = 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<PixelMap>) {
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);
}
})