From a2780ca0560c1ad273c24e34e5348a25f84409d2 Mon Sep 17 00:00:00 2001 From: Thomas Pointhuber Date: Sat, 12 Oct 2019 17:35:46 +0200 Subject: [PATCH] Add bitwse mode to Generate Image operation --- src/core/operations/GenerateImage.mjs | 107 ++++++++++++++++---------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/src/core/operations/GenerateImage.mjs b/src/core/operations/GenerateImage.mjs index fbf3d2de..dd780f18 100644 --- a/src/core/operations/GenerateImage.mjs +++ b/src/core/operations/GenerateImage.mjs @@ -6,9 +6,11 @@ import Operation from "../Operation.mjs"; import OperationError from "../errors/OperationError.mjs"; +import Utils from "../Utils.mjs"; import {isImage} from "../lib/FileType"; import {toBase64} from "../lib/Base64"; import jimp from "jimp"; +import {isWorkerEnvironment} from "../Utils"; /** * Generate Image operation @@ -32,7 +34,7 @@ class GenerateImage extends Operation { { "name": "Mode", "type": "option", - "value": ["Greyscale", "RG", "RGB", "RGBA"] + "value": ["Greyscale", "RG", "RGB", "RGBA", "Bits"] }, { "name": "Pixel Scale Factor", @@ -70,65 +72,86 @@ class GenerateImage extends Operation { "RG": 2, "RGB": 3, "RGBA": 4, + "Bits": 1/8, }; const bytesPerPixel = bytePerPixelMap[mode]; - if (input.length % bytesPerPixel !== 0) { + if (bytesPerPixel > 0 && input.length % bytesPerPixel !== 0) { throw new OperationError(`Number of bytes is not a divisor of ${bytesPerPixel}`); } const height = Math.ceil(input.length / bytesPerPixel / width); const image = await new jimp(width, height, (err, image) => {}); + if (isWorkerEnvironment()) + self.sendStatusMessage("Generate image from data..."); - let i = 0; - while (i < input.length) { - const index = i/bytesPerPixel; - const x = index % width; - const y = Math.floor(index / width); + if (mode === "Bits") { + let index = 0; + for (let j = 0; j < input.length; j++) { + const curByte = Utils.bin(input[j]); + for (let k = 0; k < 8; k++, index++) { + const x = index % width; + const y = Math.floor(index / width); - let red = 0x00; - let green = 0x00; - let blue = 0x00; - let alpha = 0xFF; - - switch (mode) { - case "Greyscale": - red = green = blue = input[i++]; - break; - - case "RG": - red = input[i++]; - green = input[i++]; - break; - - case "RGB": - red = input[i++]; - green = input[i++]; - blue = input[i++]; - break; - - case "RGBA": - red = input[i++]; - green = input[i++]; - blue = input[i++]; - alpha = input[i++]; - break; - - default: - throw new OperationError(`Unsupported Mode: (${mode})`); + const value = curByte[k] === "0" ? 0xFF : 0x00; + const pixel = jimp.rgbaToInt(value, value, value, 0xFF); + image.setPixelColor(pixel, x, y); + } } + } else { + let i = 0; + while (i < input.length) { + const index = i / bytesPerPixel; + const x = index % width; + const y = Math.floor(index / width); - try { - const pixel = jimp.rgbaToInt(red, green, blue, alpha); - image.setPixelColor(pixel, x, y); - } catch (err) { - throw new OperationError(`Error while generating image from pixel values. (${err})`); + let red = 0x00; + let green = 0x00; + let blue = 0x00; + let alpha = 0xFF; + + switch (mode) { + case "Greyscale": + red = green = blue = input[i++]; + break; + + case "RG": + red = input[i++]; + green = input[i++]; + break; + + case "RGB": + red = input[i++]; + green = input[i++]; + blue = input[i++]; + break; + + case "RGBA": + red = input[i++]; + green = input[i++]; + blue = input[i++]; + alpha = input[i++]; + break; + + default: + throw new OperationError(`Unsupported Mode: (${mode})`); + } + + try { + const pixel = jimp.rgbaToInt(red, green, blue, alpha); + image.setPixelColor(pixel, x, y); + } catch (err) { + throw new OperationError(`Error while generating image from pixel values. (${err})`); + } } } if (scale !== 1) { + if (isWorkerEnvironment()) + self.sendStatusMessage("Scale image..."); + image.scaleToFit(width*scale, height*scale, jimp.RESIZE_NEAREST_NEIGHBOR); }