Browse Source

Add bitwse mode to Generate Image operation

Thomas Pointhuber 5 năm trước cách đây
mục cha
commit
a2780ca056
1 tập tin đã thay đổi với 68 bổ sung45 xóa
  1. 68 45
      src/core/operations/GenerateImage.mjs

+ 68 - 45
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) => {});
 
-
-        let i = 0;
-        while (i < input.length) {
-            const index = i/bytesPerPixel;
-            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})`);
+        if (isWorkerEnvironment())
+            self.sendStatusMessage("Generate image from data...");
+
+        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);
+
+                    const value = curByte[k] === "0" ? 0xFF : 0x00;
+                    const pixel = jimp.rgbaToInt(value, value, value, 0xFF);
+                    image.setPixelColor(pixel, x, y);
+                }
             }
-
-            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})`);
+        } else {
+            let i = 0;
+            while (i < input.length) {
+                const index = i / bytesPerPixel;
+                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})`);
+                }
+
+                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);
         }