decomposer is now working

This commit is contained in:
Zeecka
2026-01-02 17:29:35 +01:00
parent 2ee0e97a0d
commit 40421f51bf
+81 -67
View File
@@ -4,78 +4,92 @@
"""Bits Decomposer Analyzer for Image Submissions.""" """Bits Decomposer Analyzer for Image Submissions."""
from pathlib import Path from pathlib import Path
from typing import Any, Optional
import numpy as np import numpy as np
from PIL import Image from PIL import Image
from .utils import update_data from .base_analyzer import SubprocessAnalyzer
class DecomposerAnalyzer(SubprocessAnalyzer):
"""Analyzer for bits decomposer."""
def __init__(self, *args):
super().__init__("decomposer", *args)
def get_results(self, _: Optional[str] = None) -> dict[str, Any]:
"""Analyze an image submission using bits decomposition."""
try:
img = Image.open(self.input_img)
converted = False
if img.mode == "P":
img = img.convert("RGB")
converted = True
img_np = np.array(img)
# Handle grayscale, RGB, RGBA, etc.
if len(img_np.shape) == 2:
channels = 1
else:
channels = img_np.shape[2]
if channels > 1:
channel_names = ["Red", "Green", "Blue", "Alpha"]
else:
channel_names = ["Grayscale"]
image_json = {}
# Add Superimposed RGB bit planes
if channels >= 3:
superimposed_json = []
for bit in range(8):
bit_mask = 1 << bit
rgb_planes = [((img_np[..., c] & bit_mask) >> bit) * 255 for c in range(3)]
rgb_image = np.stack(rgb_planes, axis=-1).astype(np.uint8)
rgb_img = Image.fromarray(rgb_image, mode="RGB")
img_name = f"superimposed_bit_{bit}.png"
out_path = self.output_dir / img_name
dl_path = Path(self.output_dir.name) / img_name
superimposed_json.append("/image/" + str(dl_path))
rgb_img.save(out_path)
image_json["Superimposed"] = superimposed_json
# Process individual channels
for c in range(channels):
channel_data = img_np[..., c] if channels > 1 else img_np
channel_label = channel_names[c]
channel_json = []
for bit in range(8):
bit_mask = 1 << bit
bit_plane = ((channel_data & bit_mask) >> bit) * 255
bit_img = Image.fromarray(bit_plane.astype(np.uint8), mode="L")
img_name = f"{channel_label}_bit_{bit}.png"
out_path = self.output_dir / img_name
dl_path = Path(self.output_dir.name) / img_name
channel_json.append("/image/" + str(dl_path))
bit_img.save(out_path)
image_json[channel_label] = channel_json
output = {
"status": "ok",
"images": image_json,
}
if converted:
output["note"] = (
"Image contains a color palette and was converted to RGB for processing."
)
return output
except Exception as e:
return {"status": "error", "error": str(e)}
def analyze_decomposer(input_img: Path, output_dir: Path) -> None: def analyze_decomposer(input_img: Path, output_dir: Path) -> None:
"""Analyze an image submission using bits decomposition.""" """Analyze an image submission using bits decomposition."""
img = Image.open(input_img) analyzer = DecomposerAnalyzer(input_img, output_dir)
converted = False analyzer.analyze()
if img.mode == "P":
img = img.convert("RGB")
converted = True
img_np = np.array(img)
# Handle grayscale, RGB, RGBA, etc.
if len(img_np.shape) == 2:
channels = 1
else:
channels = img_np.shape[2]
if channels > 1:
channel_names = ["Red", "Green", "Blue", "Alpha"]
else:
channel_names = ["Grayscale"]
image_json = {}
# Add Superimposed RGB bit planes
if channels >= 3:
superimposed_json = []
for bit in range(8):
bit_mask = 1 << bit
rgb_planes = [((img_np[..., c] & bit_mask) >> bit) * 255 for c in range(3)]
rgb_image = np.stack(rgb_planes, axis=-1).astype(np.uint8)
rgb_img = Image.fromarray(rgb_image, mode="RGB")
img_name = f"superimposed_bit_{bit}.png"
out_path = output_dir / img_name
dl_path = Path(output_dir.name) / img_name
superimposed_json.append("/image/" + str(dl_path))
rgb_img.save(out_path)
image_json["Superimposed"] = superimposed_json
# Process individual channels
for c in range(channels):
channel_data = img_np[..., c] if channels > 1 else img_np
channel_label = channel_names[c]
channel_json = []
for bit in range(8):
bit_mask = 1 << bit
bit_plane = ((channel_data & bit_mask) >> bit) * 255
bit_img = Image.fromarray(bit_plane.astype(np.uint8), mode="L")
img_name = f"{channel_label}_bit_{bit}.png"
out_path = output_dir / img_name
dl_path = Path(output_dir.name) / img_name
channel_json.append("/image/" + str(dl_path))
bit_img.save(out_path)
image_json[channel_label] = channel_json
output = {
"decomposer": {
"status": "ok",
"images": image_json,
}
}
if converted:
output["decomposer"][
"note"
] = "Image contains a color palette and was converted to RGB for processing."
update_data(output_dir, output)