Module refinery.units.formats.stego
Expand source code Browse git
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from enum import IntEnum
from refinery.units import Unit, Arg
from refinery.lib.structures import MemoryFile
class PIXEL_PART(IntEnum):
r = 0
g = 1
b = 2
a = 3
class stego(Unit):
"""
Decodes the RGBA (red/green/blue/alpha) values of the pixels of a given image file and outputs
these values as bytes. By default, the pixels are converted left to right, top to bottom. When
the input image is grayscale, the color channels are ignored. Colored images are converted to
RGBA mode.
"""
def __init__(
self,
split: Arg.Switch('-m', help='Emit the individual rows or columns as separate outputs.') = False,
parts: Arg('parts', nargs='?', type=str, help=(
'A string containing any ordering of the letters R, G, B, and A (case-insensitive). '
'These pixel components will be extracted from every pixel in the given order. The '
'default value is {default}.'
)) = 'RGB'
):
super().__init__(
split=split,
parts=tuple(Arg.AsOption(p, PIXEL_PART) for p in parts)
)
@Unit.Requires('Pillow', 'formats')
def _image():
from PIL import Image
return Image
def process(self, data):
split = self.args.split
parts = self.args.parts
image = self._image.open(MemoryFile(data, read_as_bytes=True))
grayscale = image.mode.startswith('L')
bw_bitmap = image.mode.startswith('1')
no_colors = grayscale or bw_bitmap
if not no_colors:
image = image.convert('RGBA')
width, height = image.size
chunk_size = 1 if no_colors else len(parts)
output = MemoryFile()
buffer = bytearray(chunk_size * width)
pixels = iter(image.getdata())
for _ in range(height):
offset = 0
for _ in range(width):
pixel = next(pixels)
next_offset = offset + chunk_size
if no_colors:
buffer[offset] = pixel
else:
buffer[offset:next_offset] = (pixel[p] for p in parts)
offset = next_offset
if split:
yield buffer
else:
output.write(buffer)
if not split:
yield output.getvalue()
Classes
class PIXEL_PART (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
An enumeration.
Expand source code Browse git
class PIXEL_PART(IntEnum): r = 0 g = 1 b = 2 a = 3
Ancestors
- enum.IntEnum
- builtins.int
- enum.Enum
Class variables
var r
var g
var b
var a
class stego (split=False, parts='RGB')
-
Decodes the RGBA (red/green/blue/alpha) values of the pixels of a given image file and outputs these values as bytes. By default, the pixels are converted left to right, top to bottom. When the input image is grayscale, the color channels are ignored. Colored images are converted to RGBA mode.
Expand source code Browse git
class stego(Unit): """ Decodes the RGBA (red/green/blue/alpha) values of the pixels of a given image file and outputs these values as bytes. By default, the pixels are converted left to right, top to bottom. When the input image is grayscale, the color channels are ignored. Colored images are converted to RGBA mode. """ def __init__( self, split: Arg.Switch('-m', help='Emit the individual rows or columns as separate outputs.') = False, parts: Arg('parts', nargs='?', type=str, help=( 'A string containing any ordering of the letters R, G, B, and A (case-insensitive). ' 'These pixel components will be extracted from every pixel in the given order. The ' 'default value is {default}.' )) = 'RGB' ): super().__init__( split=split, parts=tuple(Arg.AsOption(p, PIXEL_PART) for p in parts) ) @Unit.Requires('Pillow', 'formats') def _image(): from PIL import Image return Image def process(self, data): split = self.args.split parts = self.args.parts image = self._image.open(MemoryFile(data, read_as_bytes=True)) grayscale = image.mode.startswith('L') bw_bitmap = image.mode.startswith('1') no_colors = grayscale or bw_bitmap if not no_colors: image = image.convert('RGBA') width, height = image.size chunk_size = 1 if no_colors else len(parts) output = MemoryFile() buffer = bytearray(chunk_size * width) pixels = iter(image.getdata()) for _ in range(height): offset = 0 for _ in range(width): pixel = next(pixels) next_offset = offset + chunk_size if no_colors: buffer[offset] = pixel else: buffer[offset:next_offset] = (pixel[p] for p in parts) offset = next_offset if split: yield buffer else: output.write(buffer) if not split: yield output.getvalue()
Ancestors
Class variables
var required_dependencies
var optional_dependencies
Inherited members