Esempio n. 1
0
    def add_png_metadata(self, path, glyph):
        '''
        given the path to a png file and the glyph it contains,
        write appropriate metadata fields into the file
        '''
        self.metadata['Description'] = self.metadata[
            '_Description_tmpl'].format(glyph=glyph)
        self.metadata['Title'] = self.metadata['_Title_tmpl'].format(
            glyph=glyph,
            border=self.args['bordercolor_name'],
            color=self.args['bgcolor_name'])

        with Image.open(path) as image:
            info = PngInfo()
            for entry in ["Author", "Description", "Title", "Software"]:
                if not entry.startswith('_'):
                    info.add_itxt(entry, self.metadata[entry], "en", entry)
            basename, filename = os.path.split(path)
            newname = os.path.join(basename, 'new-' + filename)
            image.save(newname, pnginfo=info)

            if self.args['verbose']:
                with Image.open(newname) as image:
                    print("new image is", newname)
                    print(image.info)
        os.unlink(path)
        os.rename(newname, path)
Esempio n. 2
0
    def print_png(self,
                  filename_or_obj,
                  *args,
                  metadata=None,
                  pil_kwargs=None,
                  **kwargs):

        if metadata is None:
            metadata = {}
        if pil_kwargs is None:
            pil_kwargs = {}
        metadata = {
            "Software":
            f"matplotlib version{__version__}, http://matplotlib.org/",
            **metadata,
        }

        if "pnginfo" not in pil_kwargs:
            pnginfo = PngInfo()
            for k, v in metadata.items():
                pnginfo.add_text(k, v)
            pil_kwargs["pnginfo"] = pnginfo
        pil_kwargs.setdefault("dpi", (self.figure.dpi, self.figure.dpi))

        data = self.get_pixel_data()

        (Image.fromarray(data).save(filename_or_obj,
                                    format="png",
                                    **pil_kwargs))
    def _prepare_slide(self, mols, properties):

        if mols is None:
            raise ValueError(
                'Expected a list of rdkit molecule instances but got \'None\'')

        # cut-off mols + properties silently. I think this is better than raising a ValueError
        mols = mols[:self.max_mols]
        properties = properties[:self.max_mols]
        if self.number_of_properties > 0 and len(mols) != len(properties):
            raise ValueError(
                'Number of molecules must match number of properties.')

        if len(mols) == self.max_mols:
            slide = Image.new('RGBA', [self.slide_width, self.slide_height],
                              (255, 255, 255, 0))
        # less mols -> smaller image
        elif len(mols) < self.mols_per_row:
            slide = Image.new('RGBA',
                              [len(mols) * self.image_width, self.row_height],
                              (255, 255, 255, 0))
        else:
            num_rows = (len(mols) // self.mols_per_row) + 1
            slide = Image.new('RGBA',
                              [self.slide_width, self.row_height * num_rows],
                              (255, 255, 255, 0))

        png_info = PngInfo()
        png_info.add_text('numProperties', str(self.number_of_properties))

        return mols, slide, png_info
    def hide_information(self):
        """
        Method to hide a key 
        into the given image
        """

        #first of all is to change original cover file metadata
        #because if we do it later, bits will be changed and key
        # will not be recovered

        _tmp_image = self.image_object.copy()

        max_with = _tmp_image.size[0] - 1
        (coord_x, coord_y) = (0, 0)

        for pixel in self.encode_imdata(_tmp_image.getdata(),
                                        self.key_to_hide):
            _tmp_image.putpixel((coord_x, coord_y), pixel)
            if (coord_x == max_with):
                coord_x = 0
                coord_y += 1
            else:
                coord_x += 1

        #save the resulting image
        #image_format = self.image_where_to_hide.split(".")[1]
        image_format = "png"
        f_name = self.image_where_to_hide.split(
            ".")[0] + "_hide." + image_format

        metadata = PngInfo()
        metadata.add_text("url", self.url_metadata)
        metadata.add_text("language", self.url_language)

        _tmp_image.save(f_name, image_format.upper(), pnginfo=metadata)
Esempio n. 5
0
def encode(filename, mode="RGB", verbose=False):
    if mode == "P":
        print(
            "invalid choice: 'P' for PNG (choose from '1', 'L', 'RGB', 'RGBA')"
        )
        sys.exit()
    if mode not in ["RGB", "L"]:
        print(mode, "coming soon")
        sys.exit()
    try:
        with open(filename, 'rb') as f:
            data = f.read()
    except IOError as e:
        print(e)
        sys.exit()

    output_filename = change_ext(filename, "png")
    output_size, extra_bytes_lenght = calc_size(len(data), mode)
    data += (b'\0' * extra_bytes_lenght)
    metadata = PngInfo()
    metadata.add_text("filename", str(os.path.basename(filename)))
    metadata.add_text("extra_bytes", str(extra_bytes_lenght))

    if os.path.isfile(output_filename):
        output_filename = get_unique_filename(output_filename)

    im = Image.frombytes(mode, output_size, data)
    im.save(output_filename, pnginfo=metadata)
    if verbose:
        print(f"Extra bytes:  {extra_bytes_lenght}")
        print(f"Image size: {output_size}")
        print(f"Image mode: {im.mode}")
        print(f"Filename:  {output_filename}")
    sys.exit()
    def encrypt_png(self, in_path: PathType, out_path: PathType) -> None:
        image = PngImageFile(in_path)

        # convert pixels to bytes in order to encrypt them
        im_bytes = bytearray(self.__get_pixels(image))

        # get random IV and calculate MAC
        iv = get_random_bytes(CryptoAES.block_size)
        h = HMAC.new(self.__key, digestmod=SHA256)
        h.update(im_bytes)

        # create metadata object in order to save IV and MAC to image
        metadata = PngInfo()
        metadata.add_text('iv', iv.hex())
        metadata.add_text('mac', h.hexdigest())

        print(f'writing IV = {iv.hex()} and MAC = {h.hexdigest()} to image metadata')

        # encrypt image
        cipher = CryptoAES.new(self.__key, CryptoAES.MODE_ECB)
        enc_data = cipher.encrypt(im_bytes)

        # write image to file with metadata
        image.frombytes(enc_data)
        image.save(out_path, pnginfo=metadata)
Esempio n. 7
0
 def print_png(self,
               path_or_stream,
               *,
               dryrun=False,
               metadata=None,
               pil_kwargs=None,
               **kwargs):
     _check_print_extra_kwargs(**kwargs)
     img = self._get_fresh_straight_rgba8888()
     if dryrun:
         return
     metadata = {
         "Software":
         f"matplotlib version {mpl.__version__}, https://matplotlib.org",
         **(metadata if metadata is not None else {}),
     }
     if pil_kwargs is None:
         pil_kwargs = {}
     # Only use the metadata kwarg if pnginfo is not set, because the
     # semantics of duplicate keys in pnginfo is unclear.
     if "pnginfo" not in pil_kwargs:
         pnginfo = PngInfo()
         for k, v in metadata.items():
             pnginfo.add_text(k, v)
         pil_kwargs["pnginfo"] = pnginfo
     pil_kwargs.setdefault("dpi", (self.figure.dpi, self.figure.dpi))
     Image.fromarray(img).save(path_or_stream, format="png", **pil_kwargs)
Esempio n. 8
0
 def encrypt(self):
     """
     Encode in base64 the string/file, create a PNG file with previously selected
     colors; encrypt in AES-256 characters + RGB values dataset, and append to
     image as zTXt chunk; save PNG file with uuid4 filename or return image PIL object
     depending on directory parameter.
     """
     if path.isfile(self.data):
         with open(self.data, "rb") as file:
             self.data = urlsafe_b64encode(file.read()).decode('utf8')
         file.close()
     else:
         self.data = urlsafe_b64encode(self.data.encode()).decode('utf8')
     encrypted = self.encrypt_aes256(dataset=None)
     self.data = encrypted["CipherData"]
     colorslist, dataset = self.colors_list(self.data)
     imgsize = int(sqrt(len(colorslist)))
     img = Image.new(mode = "RGB", size = (imgsize, imgsize))
     img.putdata(colorslist)
     encdataset = self.encrypt_aes256(str(dataset))
     metadata = PngInfo()
     metadata.add_text("Dataset", encdataset["CipherData"], zip = True)
     metadata.add_text("DatasetNonce", encdataset["Nonce"], zip = True)
     metadata.add_text("DatasetSalt", encdataset["Salt"], zip = True)
     metadata.add_text("DatasetTag", encdataset["Tag"], zip = True)
     metadata.add_text("DataNonce", encrypted["Nonce"], zip = True)
     metadata.add_text("DataSalt", encrypted["Salt"], zip = True)
     metadata.add_text("DataTag", encrypted["Tag"], zip = True)
     if not self.directory:
         b = BytesIO()
         img.save(b, "PNG", pnginfo = metadata)
         b.seek(0)
         return b
     img.save(self.directory + sep + str(uuid4()) + ".png", "PNG", pnginfo = metadata)
Esempio n. 9
0
    def ExportPicture(self, index, path):
        pnginfo = PngInfo()
        pnginfo.add_text("Software", "FlashGBX")
        pnginfo.add_text("Source", "Pocket Camera")
        pnginfo.add_text("Creation Time", email.utils.formatdate())

        if index == 0:
            pic = self.GetPicture(0)
            pnginfo.add_text("Title", "Game Face")
        else:
            pic = self.GetPicture(index)
            pnginfo.add_text("Title", "Photo {:02d}".format(index))

        ext = os.path.splitext(path)[1]
        if ext.lower() == ".png":
            outpic = pic
            outpic.save(path, pnginfo=pnginfo)
        elif ext.lower() == ".gif":
            outpic = pic
            outpic.save(path)
        elif ext.lower() in (".jpg", ".jpeg"):
            outpic = pic.convert("RGB")
            outpic.save(path, quality=100, subsampling=0)
        else:
            outpic = pic.convert("RGB")
            outpic.save(path)
Esempio n. 10
0
def resize_card(image_load_args, fmt, height, axis):
    try:
        image = load_image(*image_load_args)
    except IOError:
        return (1, None)

    scalefactor = height / (image.height if axis == "h" else image.width)

    if image.format == "PNG" and (image.mode != "RGB" or image.mode != "RGBA"):
        image = image.convert("RGBA")

    image = image.resize(
        (round(image.width * scalefactor), round(image.height * scalefactor)),
        reducing_gap=3.0)
    bio = io.BytesIO()
    try:
        if fmt == "jpg":
            image.save(bio,
                       "jpeg",
                       quality=90,
                       exif=make_exif(b"SkyfarerGalleryResizeTag"))
        else:
            meta = PngInfo()
            meta.add_text("Skyfarer", f"GalleryResizeTag")
            image.save(bio, "png", optimize=True, pnginfo=meta)
    except IOError as e:
        return (3, None)

    return (0, bio.getvalue())
Esempio n. 11
0
def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "t:o:s:h",
                                   ["text=", "output=", "script=", "help"])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    text = None
    script = None
    for o, a in opts:
        if o in ("-t", "--text"):
            text = a
        elif o in ("-o", "--output"):
            output = a
        elif o in ("-s", "--script"):
            script = a
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        else:
            assert False, "unhandled option"

    img = scriptList[script](text, method=Image.LANCZOS)

    metadata = PngInfo()
    metadata.add_itxt("Content", text)

    img.save(output, pnginfo=metadata)
Esempio n. 12
0
def test_pil_kwargs_png():
    from PIL.PngImagePlugin import PngInfo
    buf = io.BytesIO()
    pnginfo = PngInfo()
    pnginfo.add_text("Software", "test")
    plt.figure().savefig(buf, format="png", pil_kwargs={"pnginfo": pnginfo})
    im = Image.open(buf)
    assert im.info["Software"] == "test"
Esempio n. 13
0
def display_pil_image(img):
    """displayhook function for PIL Images, rendered as PNG"""
    # pull metadata from the image, if there
    metadata = PngInfo()
    for k, v in img.info.items():
        metadata.add_text(k, v)
    bio = BytesIO()
    img.save(bio, format='PNG', pnginfo=metadata)
    return bio.getvalue()
Esempio n. 14
0
def test_imsave_pil_kwargs_png():
    from PIL.PngImagePlugin import PngInfo
    buf = io.BytesIO()
    pnginfo = PngInfo()
    pnginfo.add_text("Software", "test")
    plt.imsave(buf, [[0, 1], [2, 3]],
               format="png", pil_kwargs={"pnginfo": pnginfo})
    im = Image.open(buf)
    assert im.info["Software"] == "test"
Esempio n. 15
0
    def __init__(self, image: ndarray, from_color_space: str = None, to_color_space: str = None):
        raiseif(
            not isinstance(image, ndarray),
            UnearthtimeException(f'Image is type [{type(image)}] and must be type `numpy.ndarray`')
        )

        self.__image, self.__color_space = Image.__resolve_image(image, from_color_space, to_color_space)
        self.__hash = 0
        self.__height, self.__width = image.shape[0], image.shape[1]
        self.__info = PngInfo()
Esempio n. 16
0
def patch_image():  # <- image with a text inside can be loaded as a playlist
    with open("proto_image.png", mode="rb") as i:
        img = Image.open(i)

        info = PngInfo()

        with open("attacking_playlist.m3u") as pl:
            text = pl.read()

        info.add_text("attack", text)
        img.save("vuln_image.png", "PNG", pnginfo=info)
Esempio n. 17
0
def add_tags_to_png_file(fpath):
    try:
        info = create_file_info(fpath)
        png_image = PngImageFile(open(fpath, 'rb'))
        png_info = PngInfo()
        for k, v in info.items():
            png_info.add_text(k, v)
        png_image.save(fpath, pnginfo=png_info)
    except (Exception, OSError):
        print("WARNING: Could not add debug info to file '{}'.".format(fpath))
        traceback.print_exc()
Esempio n. 18
0
 def _include_provenance_png(filename, attributes):
     pnginfo = PngInfo()
     exif_tags = {
         'provenance': 'ImageHistory',
         'caption': 'ImageDescription',
         'software': 'Software',
     }
     for key, value in attributes.items():
         pnginfo.add_text(exif_tags.get(key, key), value, zip=True)
     with Image.open(filename) as image:
         image.save(filename, pnginfo=pnginfo)
Esempio n. 19
0
def stack_card(image_load_args, fmt, frame_num, role_num, attr_num):
    global G_CARD_ICON_ATLAS

    if not frame_num < 4:
        return (1, None)
    if not role_num < 5:
        return (1, None)
    if not attr_num < 7:
        return (1, None)

    if not G_CARD_ICON_ATLAS:
        try:
            G_CARD_ICON_ATLAS = Image.open(
                os.path.join(os.path.dirname(__file__), "assets",
                             "cardicons.png"))
        except IOError:
            return (1, None)

    try:
        face = load_image(*image_load_args)
    except IOError:
        return (1, None)

    icon = Image.new("RGBA", (128, 128))
    icon.paste(face, ((icon.size[0] - face.size[0]) // 2,
                      (icon.size[1] - face.size[1]) // 2))
    if frame_num:
        icon.alpha_composite(G_CARD_ICON_ATLAS,
                             source=frame_coordinate[frame_num])
    if attr_num:
        icon.alpha_composite(G_CARD_ICON_ATLAS, (97, 3),
                             attribute_coordinate[attr_num])
    if role_num:
        icon.alpha_composite(G_CARD_ICON_ATLAS, (2, 98),
                             role_coordinate[role_num])

    bio = io.BytesIO()
    try:
        if fmt == "jpg":
            icon.convert("RGB").save(bio,
                                     "jpeg",
                                     quality=90,
                                     exif=make_icon_exif(
                                         frame_num, attr_num, role_num))
        else:
            meta = PngInfo()
            meta.add_text("Skyfarer",
                          f"v:2,f:{frame_num},a:{attr_num},r:{role_num}")
            icon.save(bio, "png", optimize=True, pnginfo=meta)
    except IOError:
        return (3, None)

    return (0, bio.getvalue())
Esempio n. 20
0
def capture():
    if args is None:
        raise RuntimeError("Something horribly wrong has happened")
    if "pullTime" not in request.form:
        return {"error": "No pull time!"}, 400
    pull_time = request.form["pullTime"]
    if not pull_time.isdigit():
        return {"error": "Invalid pull time"}, 400
    pull_time = int(pull_time)
    img = request.form["image"]
    resp = urlopen(img)

    machine = request.form["machine"]
    now = int(time.time())
    ext = ".png"
    name = f"{now}-{machine}{ext}"
    fs, path = mkstemp(suffix=ext)
    os.close(fs)
    try:
        with open(path, "wb") as ofs:
            ofs.write(resp.file.read())
        img = load_img(path)
    finally:
        os.remove(path)
    # Simple way of storing more information about the image
    metadata = PngInfo()
    fields_to_not_attach = {"image"}
    for key, value in request.form.items():
        if key in fields_to_not_attach:
            continue
        metadata.add_text(key, value)

    # Don't do this every request
    if args.capture_split:
        split_ratios = [int(x) for x in args.split_ratio.split(",")]
        ratio_total = sum(split_ratios)
        rand = random.randint(0, ratio_total)
        limit = 0
        for i, split in enumerate(split_ratios):
            limit += split
            if rand <= limit:
                output_dir = os.path.join(args.capture_dir, OUTPUTS[i])
                if not os.path.isdir(output_dir):
                    os.mkdir(output_dir)
                output_dir = os.path.join(output_dir, str(pull_time))
                break
    else:
        output_dir = os.path.join(args.capture_dir, str(pull_time))
    if not os.path.isdir(output_dir):
        os.mkdir(output_dir)
    img.save(os.path.join(output_dir, name), pnginfo=metadata)
    return {}
Esempio n. 21
0
 def savemeta(*args, **kwargs):
     path = args[1]
     if path.endswith(".fig"):
         import pickle as pkl
         pkl.dump(args[0], open(path, 'wb'))
     else:
         mpl_savefig(*args, **kwargs)
         #fig = args[0]
         if path.endswith(".png"):
             targetImage = PngImageFile(path)
             metadata = PngInfo()
             metadata.add_text("Description", str(meta))
             targetImage.save(path, pnginfo=metadata)
Esempio n. 22
0
 def saveImg(self, path):
     """
     Save information as an image
     """
     arr = self.grid
     arr[self.coffset[1], self.coffset[0]] = 0.8
     # Save map info
     meta = PngInfo()
     meta.add_text("iposx", str(self.ipos[0]))
     meta.add_text("iposy", str(self.ipos[1]))
     meta.add_text("tsize", str(self.tsize))
     arr = np.flipud(arr)        
     img = Image.fromarray(np.uint8(arr * 255), 'L')
     img.save(path, "PNG", pnginfo=meta)
Esempio n. 23
0
def write_png_metadata(filename, settings):
    targetImage = PngImageFile(filename)
    metadata = PngInfo()
    for (k, v) in settings.items():
        if type(v) == list:
            value = ""
            for item in v:
                value += str(item) + " "
            v = value
        if type(v) == bool:
            v = str(v)
        if v is None:
            continue
        else:
            metadata.add_text(k, str(v))
    targetImage.save(filename, pnginfo=metadata)
Esempio n. 24
0
    def sample_image_path(self):
        """Copy the sample image to to a unique file name and return the path.

		Returns:
			tuple of (the filename, the new sample image path)
		"""
        filename = self.generate_alphanumeric() + ".png"
        new_file = self.tmp_file_path(filename)
        shutil.copy(self.original_sample_image_path, new_file)

        # make the image content unique
        image_file = PngImageFile(open(new_file, "r"))
        info = PngInfo()
        info.add_text('Comment', self.generate_alphanumeric(length=30))
        image_file.save(new_file, pnginfo=info)
        self.temp_files.append(new_file)
        return (filename, new_file)
    def decrypt_png(self, in_path: PathType, out_path: PathType) -> None:
        image = PngImageFile(in_path)
        iv: Optional[str] = None
        mac: Optional[str] = None

        # try to get IV from metadata
        try:
            iv = image.text['iv']

            print(f'found IV = {iv}')
        except KeyError:
            print('IV was not found in file')

        # try to get MAC from metadata
        try:
            mac = image.text['mac']

            print(f'found MAC = {mac}')
        except KeyError:
            print('MAC was not found in file')

        # convert pixels to bytes in order to decrypt them
        im_bytes = bytearray(self.__get_pixels(image))

        # decrypt image
        cipher = CryptoAES.new(self.__key, CryptoAES.MODE_ECB)
        dec: bytes = cipher.decrypt(im_bytes)

        # try to verify MAC
        try:
            self.__hmac.update(dec)
            self.__hmac.verify(bytes.fromhex(mac))

            print('MAC is valid')
        except ValueError:
            print('MAC is invalid')

        # don't forget about metadata
        metadata = PngInfo()
        metadata.add_text('iv', iv)
        metadata.add_text('mac', mac)

        # save decrypted image to file
        image.frombytes(dec)
        image.save(out_path, pnginfo=metadata)
Esempio n. 26
0
    def segment_image(filename,
                      image,
                      mask,
                      root_max_radius=15,
                      min_dimension=50,
                      smooth=1):
        #mask = _nd.binary_erosion(mask==mask.max(), iterations=
        mask = mask == mask.max()

        # find the bounding box, and crop image and mask
        bbox = _nd.find_objects(mask)[0]
        mask = mask[bbox]
        img = image[bbox]

        if smooth:
            smooth_img = _nd.gaussian_filter(img * mask, sigma=smooth)
            smooth_img /= _np.maximum(
                _nd.gaussian_filter(mask.astype('f'), sigma=smooth), 2**-10)
            img[mask] = smooth_img[mask]

        # background removal
        _print_state(verbose, 'remove background')
        img = _remove_background(img, distance=root_max_radius, smooth=1)
        img *= _nd.binary_erosion(mask, iterations=root_max_radius)

        # image binary segmentation
        _print_state(verbose, 'segment binary mask')
        rmask = _segment_root(img)
        rmask[-mask] = 0
        if min_dimension > 0:
            cluster = _nd.label(rmask)[0]
            cluster = _clean_label(cluster, min_dim=min_dimension)
            rmask = cluster > 0

        # save the mask, and bbox
        from PIL.PngImagePlugin import PngInfo
        meta = PngInfo()
        meta.add_text(
            'bbox',
            repr([(bbox[0].start, bbox[0].stop),
                  (bbox[1].start, bbox[1].stop)]))
        _Image(rmask).save(filename, dtype='uint8', scale=255, pnginfo=meta)

        return rmask, bbox
Esempio n. 27
0
def replace_meta(filename, fields):
    metaname = get_dumpfile(filename)
    with open(metaname) as json_file:
        meta = json.load(json_file)
    if fields and fields[0] != '*':
        print(f"overwriting metadata[{fields}] in {filename} from {metaname}")
        newmeta = {}
        for f in fields:
            newmeta[f] = meta[f]
    else:
        print(f"overwriting metadata in {filename} from {metaname}")
        newmeta = meta

    newmeta['Metadata Modification Time'] = f"{datetime.now()}"
    img = PngImageFile(filename)
    metadata = PngInfo()
    for f in newmeta:
        metadata.add_text(f, newmeta[f])
    img.save(filename, pnginfo=metadata)
Esempio n. 28
0
    def compute_circle(filename, image, circle_number):
        from ..image.circle import detect_circles
        cmask = _nd.binary_opening(image > .45, iterations=5)
        cluster = _nd.label(cmask)[0]
        cluster = _clean_label(cluster, min_dim=30)

        ind, qual, c, dmap = detect_circles(n=circle_number, cluster=cluster)
        radius = qual**.5 / _np.pi

        #cind = _np.zeros(c.max()+1)
        #cind[ind] = _np.arange(1,len(ind)+1)
        #cmask = cind[c]

        from PIL.PngImagePlugin import PngInfo
        meta = PngInfo()
        meta.add_text('circles', repr(ind.tolist()))
        meta.add_text('radius', repr(radius.tolist()))
        _Image(cluster).save(filename, dtype='uint8', scale=1, pnginfo=meta)
        #_Image(cmask).save(filename, dtype='uint8', scale=1)

        return cluster, ind, radius
Esempio n. 29
0
    def on_save_clicked(self, button):
        current_path = self.entry.get_text()

        # write metadata
        metadata = PngInfo()
        metadata.add_text("screenshat", self.entryy.get_text())

        img = PngImageFile(img_path)
        img.save(img_path, pnginfo=metadata)
        

        # Update config file
        pathlib.Path(config_path).write_text(current_path)
        
        # in doubt do mkdir -p new directory
        pathlib.Path(current_path).mkdir(parents=True, exist_ok=True)

        # move file 
        shutil.move(img_path, current_path)

        self.destroy()
Esempio n. 30
0
    def encode_to_img(self, secret: str, scale: bool = True) -> PixelImage:
        """Encodes secret to a colorful png square

        Parameters
        ___________
        secret: str
            Secret to be encoded consisting of any utf8 chars including
            whitespace ones
        scale: bool = True
            Whether or not to enlarge output image. Only enourmous secrets
            will produce image bigger than a couple pixels by a couple pixels
            which is miserable to look at.
            Basically a choice of aesthetics over pragmatism"""

        self.encode(secret)
        edge, *_ = self.arr.shape
        metadata = PngInfo()
        if scale and (scale_up := (self.max_scale_up // edge)) > 1:
            s = edge * scale_up
            img = Image.fromarray(self.arr).resize((s, s), Image.NEAREST)
            metadata.add_text("edge", str(edge))
            return PixelImage(img, pnginfo=metadata)