Ejemplo n.º 1
0
	def draw_alpha_frames_merged(self):
		for idx, bmode in enumerate(self.blending_modes):

			max_w = 0
			max_h = 0

			blendomatic_frames = []

			for tile in bmode["alphamasks"]:
				frame = PNG(0, None, tile["data"])
				tw = tile["width"]
				th = tile["height"]
				frame.create(tw, th, True)

				if tw > max_w:
					max_w = tw
				if th > max_h:
					max_h = th

				blendomatic_frames.append((frame, None, (0, 0)))

			atlas, atlas_meta, (width, height) = merge_frames(blendomatic_frames, max_w, max_h)
			meta_out = generate_meta_text(atlas_meta)

			yield idx, atlas, (width, height), meta_out
Ejemplo n.º 2
0
    def draw_frames_merged(self, color_table):
        # generate all frames, them merge them on one big texture

        # player-specific colors will be in color blue, but with an alpha of 254
        player_id = 1

        max_width = 0
        max_height = 0

        slp_pngs = []
        for frame in self.frames:
            png = PNG(player_id, color_table, frame.get_picture_data())
            png.create()

            if png.width > max_width:
                max_width = png.width

            if png.height > max_height:
                max_height = png.height

            slp_pngs.append((png, frame.info.size, frame.info.hotspot))

            # now we collected all sprites and can start merging them to one
            # big texture atlas.
        atlas, atlas_meta, (width, height) = merge_frames(slp_pngs, max_width, max_height)

        meta_out = generate_meta_text(atlas_meta)

        return atlas, (width, height), meta_out
Ejemplo n.º 3
0
	def draw_bit_frames(self):
		for idx, bmode in enumerate(self.blending_modes):

			for tidx, tile in enumerate(bmode["bitmasks"]):
				png = PNG(0, None, tile["data"])
				png.create(tile["width"], tile["height"], True)

				yield png, idx, tidx
Ejemplo n.º 4
0
def main():
    parsed = init()

    # In insert mode
    with parsed.carrier as image:
        data = image.read()
    original_image = PNG(data, verbose=VERBOSE)

    if parsed.secret:
        modified_image = insert(original_image, parsed.secret)
        output_data = modified_image.export_image()
    else:
        # in extract mode
        output_data = extract(original_image)

        print('Secret message: "{}"'.format(output_data.decode(ENCODING)))

    # After finished parsing, output file
    with parsed.output_file as output_file:
        output_file.write(output_data)

    # Print file statistics
    file_metadata("Original file information:", parsed.carrier.name, data)
    file_metadata("Exported file information:", parsed.output_file.name,
                  output_data)
Ejemplo n.º 5
0
    def write_glyphs(self, glyphs, glyph_filenames, image_format):

        write_func = self.image_write_func(image_format)
        for glyph in glyphs:
            img_file = glyph_filenames[glyph]
            offset = self.tell()
            write_func(PNG(img_file))
            self.glyph_maps.append(GlyphMap(glyph, offset, image_format))
Ejemplo n.º 6
0
    def write_glyphs(self, glyphs, glyph_filenames, image_format):

        write_func = self.image_write_func(image_format)
        for glyph in glyphs:
            img_file = glyph_filenames[glyph]
            # print 'writing data for glyph %s' % path.basename(img_file)
            offset = self.tell()
            write_func(PNG(img_file))
            self.glyph_maps.append(GlyphMap(glyph, offset, image_format))
Ejemplo n.º 7
0
    def draw_frames(self, color_table):
        # player-specific colors will be in color blue, but with an alpha of 254
        player_id = 1

        for idx, frame in enumerate(self.frames):
            png = PNG(player_id, color_table, frame.get_picture_data())
            png.create()

            # this sprite png only contains one texture, therefore x and y are 0
            drawn_meta = {
                "tx": 0,
                "ty": 0,
                "tw": frame.info.size[0],
                "th": frame.info.size[1],
                "hx": frame.info.hotspot[0],
                "hy": frame.info.hotspot[1],
            }

            meta_out = generate_meta_text([drawn_meta])

            yield png, meta_out
Ejemplo n.º 8
0
 def save(self, filename):
     # Initialize an array to hold the colors converted
     # to 32 bit unsigned integers
     intData = []
     for x in range(self.width):
         intData.append([])
         for y in range(self.height):
             argb = self.data[x][y]
             # Reorder the alpha to the back
             intData[-1].append(CTI(argb[1], argb[2], argb[3], argb[0]))
     # Actually save the information to a file
     PNG(intData, filename)
Ejemplo n.º 9
0
    def saveDepth(self, filename):
        minDepth = None
        maxDepth = None

        # Find the range of values in the depth array
        for x in range(self.width):
            for y in range(self.height):
                depthVal = self.depth[x][y]
                if depthVal is not None:
                    if maxDepth is None or depthVal > maxDepth:
                        maxDepth = depthVal
                    if minDepth is None or depthVal < minDepth:
                        minDepth = depthVal

        # Define a method for reverse linear (inter/extra)polation.
        def RLerp(v0, v1, val):
            return float(val - v0) / float(v1 - v0)

        # Create visual for depth
        intData = []
        # First make sure min/max are different and not None
        if minDepth is None or maxDepth is None or minDepth == maxDepth:
            # There is no real depth information,  white screen
            for x in range(self.width):
                intData.append([])
                for y in range(self.height):
                    intData[-1].append(0x00000000)
        else:
            # Depth information exists and makes sense
            for x in range(self.width):
                intData.append([])
                for y in range(self.height):
                    depthVal = self.depth[x][y]
                    if depthVal is not None:
                        depthScale = RLerp(minDepth, maxDepth, depthVal)
                        depthColor = int(depthScale * 255)
                        intData[-1].append(
                            CTI(depthColor, depthColor, depthColor, 255))
                    else:
                        intData[-1].append(CTI(0, 0, 0, 0))
        PNG(intData, filename)
Ejemplo n.º 10
0
img_pairs.sort(key=lambda pair: (len(pair[0]), pair[0]), reverse=True)

# Add dummy GlyphOrder
for code in [
        0x23, 0x2a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
        0x20e3, 0x200d, 0x1f9b0, 0x1f9b1, 0x1f9b2, 0x1f9b3, 0xfe0f, 0xe0062,
        0xe0063, 0xe0065, 0xe0067, 0xe006c, 0xe006e, 0xe0073, 0xe0074, 0xe0077,
        0xe007f
]:
    g.append("%04X" % code)

for (u, filename) in img_pairs:
    codes = u.split("-")
    n = glyph_name(codes)
    print "Adding glyph for %s" % n
    g.append(n)
    for code in codes:
        code = int(code, 16)
        if code not in c:
            name = glyph_name(["%04X" % code])
            c[code] = name
            if len(codes) > 1:
                h[name] = [0, 0]
    (img_width, img_height) = PNG(filename).get_size()
    advance = int(round((float(ascent + descent) * img_width / img_height)))
    h[n] = [advance, 0]
    if len(codes) > 1:
        add_ligature(font, codes)

font.saveXML(out_file)
Ejemplo n.º 11
0
 def map_fn(filename):
     wid, ht = PNG(filename).get_size()
     return int(round(float(lineheight) * wid / ht))
Ejemplo n.º 12
0
 def setUp(self):
     png_path = os.path.join(fixtures_dir, 'gogopher.png')
     self.png = PNG(open(png_path))
Ejemplo n.º 13
0
def main(argv):
    import glob
    from fontTools import ttx, ttLib

    options = []

    option_map = {
        "-V": "verbose",
        "-O": "keep_outlines",
        "-U": "uncompressed",
        "-C": "keep_chunks",
    }

    for key, value in option_map.items():
        if key in argv:
            options.append(value)
            argv.remove(key)

    if len(argv) < 4:
        print >> sys.stderr, """
Usage:

emoji_builder.py [-V] [-O] [-U] [-A] font.ttf out-font.ttf strike-prefix...

This will search for files that have strike-prefix followed
by a hex number, and end in ".png".  For example, if strike-prefix
is "icons/uni", then files with names like "icons/uni1f4A9.png" will
be loaded.  All images for the same strike should have the same size
for best results.

If multiple strike-prefix parameters are provided, multiple
strikes will be embedded, in the order provided.

The script then embeds color bitmaps in the font, for characters
that the font already supports, and writes the new font out.

If -V is given, verbose mode is enabled.

If -U is given, uncompressed images are stored (imageFormat=1).
By default, PNG images are stored (imageFormat=17).

If -O is given, the outline tables ('glyf', 'CFF ') and
related tables are NOT dropped from the font.
By default they are dropped.

If -C is given, unused chunks (color profile, etc) are NOT
dropped from the PNG images when embedding.
By default they are dropped.
"""
        sys.exit(1)

    font_file = argv[1]
    out_file = argv[2]
    img_prefixes = argv[3:]
    del argv

    def add_font_table(font, tag, data):
        tab = ttLib.tables.DefaultTable.DefaultTable(tag)
        tab.data = str(data)
        font[tag] = tab

    def drop_outline_tables(font):
        for tag in ['cvt ', 'fpgm', 'glyf', 'loca', 'prep', 'CFF ', 'VORG']:
            try:
                del font[tag]
            except KeyError:
                pass

    print

    font = ttx.TTFont(font_file)
    print "Loaded font '%s'." % font_file

    font_metrics = FontMetrics(font['head'].unitsPerEm,
                               font['hhea'].ascent,
                               -font['hhea'].descent)
    print "Font metrics: upem=%d ascent=%d descent=%d." % \
          (font_metrics.upem, font_metrics.ascent, font_metrics.descent)
    glyph_metrics = font['hmtx'].metrics
    unicode_cmap = font['cmap'].getcmap(3, 10)
    if not unicode_cmap:
        unicode_cmap = font['cmap'].getcmap(3, 1)
    if not unicode_cmap:
        raise Exception("Failed to find a Unicode cmap.")

    image_format = 1 if 'uncompressed' in options else 17

    ebdt = CBDT(font_metrics, options)
    ebdt.write_header()
    eblc = CBLC(font_metrics, options)
    eblc.write_header()
    eblc.start_strikes(len(img_prefixes))

    for img_prefix in img_prefixes:

        print

        img_files = {}
        glb = "%s*.png" % img_prefix
        print "Looking for images matching '%s'." % glb
        pattern = re.compile("^[A-Fa-f0-9]+$")
        for img_file in glob.glob(glb):
            if not pattern.match(img_file[len(img_prefix):-4]):
                continue
            uchar = int(img_file[len(img_prefix):-4], 16)
            img_files[uchar] = img_file
        if not img_files:
            raise Exception("No image files found in '%s'." % glb)
        print "Found images for %d characters in '%s'." % (len(img_files), glb)

        glyph_imgs = {}
        advance = width = height = 0
        for uchar, img_file in img_files.items():
            if uchar in unicode_cmap.cmap:
                glyph_name = unicode_cmap.cmap[uchar]
                glyph_id = font.getGlyphID(glyph_name)
                glyph_imgs[glyph_id] = img_file
                if "verbose" in options:
                    print "Matched U+%04X: id=%d name=%s image=%s" % (uchar, glyph_id, glyph_name, img_file)

                advance += glyph_metrics[glyph_name][0]
                w, h = PNG(img_file).get_size()
                width += w
                height += h

        glyphs = sorted(glyph_imgs.keys())
        if not glyphs:
            raise Exception("No common characteres found between font and '%s'." % glb)
        print "Embedding images for %d glyphs for this strike." % len(glyphs)

        advance, width, height = (div(x, len(glyphs)) for x in (advance, width, height))
        strike_metrics = StrikeMetrics(font_metrics, advance, width, height)
        print "Strike ppem set to %d." % (strike_metrics.y_ppem)

        ebdt.start_strike(strike_metrics)
        ebdt.write_glyphs(glyphs, glyph_imgs, image_format)
        glyph_maps = ebdt.end_strike()

        eblc.write_strike(strike_metrics, glyph_maps)

    print

    ebdt = ebdt.data()
    add_font_table(font, 'CBDT', ebdt)
    print "CBDT table synthesized: %d bytes." % len(ebdt)
    eblc.end_strikes()
    eblc = eblc.data()
    add_font_table(font, 'CBLC', eblc)
    print "CBLC table synthesized: %d bytes." % len(eblc)

    print

    if 'keep_outlines' not in options:
        drop_outline_tables(font)
        print "Dropped outline ('glyf', 'CFF ') and related tables."

    font.save(out_file)
    print "Output font '%s' generated." % out_file
Ejemplo n.º 14
0
def main():
    png = PNG("sample.png")
    png.load_image()
Ejemplo n.º 15
0
def main(argv):
    import glob
    from fontTools import ttx, ttLib

    options = []

    option_map = {
        "-V": "verbose",
        "-O": "keep_outlines",
        "-U": "uncompressed",
        "-S": "small_glyph_metrics",
        "-C": "keep_chunks",
    }

    for key, value in option_map.items():
        if key in argv:
            options.append(value)
            argv.remove(key)

    if len(argv) < 4:
        print("""
Usage:

emoji_builder.py [-V] [-O] [-U] [-S] [-A] font.ttf out-font.ttf strike-prefix...

This will search for files that have strike-prefix followed
by a hex number, and end in ".png".  For example, if strike-prefix
is "icons/uni", then files with names like "icons/uni1f4A9.png" will
be loaded.  All images for the same strike should have the same size
for best results.

If multiple strike-prefix parameters are provided, multiple
strikes will be embedded, in the order provided.

The script then embeds color bitmaps in the font, for characters
that the font already supports, and writes the new font out.

If -V is given, verbose mode is enabled.

If -U is given, uncompressed images are stored (imageFormat=1).

If -S is given, PNG images are stored with small glyph metrics (imageFormat=17).

By default, PNG images are stored with big glyph metrics (imageFormat=18).

If -O is given, the outline tables ('glyf', 'CFF ') and
related tables are NOT dropped from the font.
By default they are dropped.

If -C is given, unused chunks (color profile, etc) are NOT
dropped from the PNG images when embedding.
By default they are dropped.
""",
              file=sys.stderr)
        sys.exit(1)

    font_file = argv[1]
    out_file = argv[2]
    img_prefixes = argv[3:]
    del argv

    def add_font_table(font, tag, data):
        tab = ttLib.tables.DefaultTable.DefaultTable(tag)
        tab.data = str(data)
        font[tag] = tab

    def drop_outline_tables(font):
        for tag in ['cvt ', 'fpgm', 'glyf', 'loca', 'prep', 'CFF ', 'VORG']:
            try:
                del font[tag]
            except KeyError:
                pass

    print()

    font = ttx.TTFont(font_file)
    print("Loaded font '%s'." % font_file)

    font_metrics = FontMetrics(font['head'].unitsPerEm, font['hhea'].ascent,
                               -font['hhea'].descent)
    print("Font metrics: upem=%d ascent=%d descent=%d." % \
          (font_metrics.upem, font_metrics.ascent, font_metrics.descent))
    glyph_metrics = font['hmtx'].metrics
    unicode_cmap = font['cmap'].getcmap(3, 10)
    if not unicode_cmap:
        unicode_cmap = font['cmap'].getcmap(3, 1)
    if not unicode_cmap:
        raise Exception("Failed to find a Unicode cmap.")

    image_format = 1 if 'uncompressed' in options else (
        17 if 'small_glyph_metrics' in options else 18)

    ebdt = CBDT(font_metrics, options)
    ebdt.write_header()
    eblc = CBLC(font_metrics, options)
    eblc.write_header()
    eblc.start_strikes(len(img_prefixes))

    def is_vs(cp):
        return cp >= 0xfe00 and cp <= 0xfe0f

    for img_prefix in img_prefixes:
        print()

        img_files = {}
        glb = "%s*.png" % img_prefix
        print("Looking for images matching '%s'." % glb)
        for img_file in glob.glob(glb):
            codes = img_file[len(img_prefix):-4]
            if "_" in codes:
                pieces = codes.split("_")
                cps = [int(code, 16) for code in pieces]
                uchars = "".join([unichr(cp) for cp in cps if not is_vs(cp)])
            else:
                cp = int(codes, 16)
                if is_vs(cp):
                    print("ignoring unexpected vs input %04x" % cp)
                    continue
                uchars = unichr(cp)
            img_files[uchars] = img_file
        if not img_files:
            raise Exception("No image files found in '%s'." % glb)
        print("Found images for %d characters in '%s'." %
              (len(img_files), glb))

        glyph_imgs = {}
        advance = width = height = 0
        for uchars, img_file in img_files.items():
            if len(uchars) == 1:
                try:
                    glyph_name = unicode_cmap.cmap[ord(uchars)]
                except:
                    print("no cmap entry for %x" % ord(uchars))
                    raise ValueError("%x" % ord(uchars))
            else:
                glyph_name = get_glyph_name_from_gsub(uchars, font,
                                                      unicode_cmap.cmap)
            glyph_id = font.getGlyphID(glyph_name)
            glyph_imgs[glyph_id] = img_file
            if "verbose" in options:
                uchars_name = ",".join(["%04X" % ord(char) for char in uchars])
                # print "Matched U+%s: id=%d name=%s image=%s" % (
                #    uchars_name, glyph_id, glyph_name, img_file)

            advance += glyph_metrics[glyph_name][0]
            w, h = PNG(img_file).get_size()
            width += w
            height += h

        glyphs = sorted(glyph_imgs.keys())
        if not glyphs:
            raise Exception(
                "No common characters found between font and '%s'." % glb)
        print("Embedding images for %d glyphs for this strike." % len(glyphs))

        advance, width, height = (div(x, len(glyphs))
                                  for x in (advance, width, height))
        strike_metrics = StrikeMetrics(font_metrics, advance, width, height)
        print("Strike ppem set to %d." % (strike_metrics.y_ppem))

        ebdt.start_strike(strike_metrics)
        ebdt.write_glyphs(glyphs, glyph_imgs, image_format)
        glyph_maps = ebdt.end_strike()

        eblc.write_strike(strike_metrics, glyph_maps)

    print()

    ebdt = ebdt.data()
    add_font_table(font, 'CBDT', ebdt)
    print("CBDT table synthesized: %d bytes." % len(ebdt))
    eblc.end_strikes()
    eblc = eblc.data()
    add_font_table(font, 'CBLC', eblc)
    print("CBLC table synthesized: %d bytes." % len(eblc))

    print()

    if 'keep_outlines' not in options:
        drop_outline_tables(font)
        print("Dropped outline ('glyf', 'CFF ') and related tables.")

# hack removal of cmap pua entry for unknown flag glyph.  If we try to
# remove it earlier, getGlyphID dies.  Need to restructure all of this
# code.
    font_data.delete_from_cmap(font, [0xfe82b])

    font.save(out_file)
    print("Output font '%s' generated." % out_file)
Ejemplo n.º 16
0
#!/usr/bin/env python3

from png import PNG, chunks, filter

WIDTH = HEIGHT = 50

data = WIDTH * HEIGHT * bytes([255, 0, 0])

p = PNG()
p.chunks.append(chunks.IHDR(width=WIDTH, height=HEIGHT))
p.chunks.append(chunks.IDAT(uncompressed_data=filter.encode(data, WIDTH*3)))
p.chunks.append(chunks.IEND())

with open("/tmp/test.png", "wb") as f:
	f.write(p.dump())
Ejemplo n.º 17
0
#!/usr/bin/env python3

PROG_NAME = "PNG Chunk Dump"

from png import PNG
import argparse

import logging

p = argparse.ArgumentParser(prog=PROG_NAME, description="Analyzes and edits PNG Chunks")
p.add_argument("-i", "--ignore-errors", action="store_true", help="Ignore Length, Name and CRC errors")
p.add_argument("-v", "--verbose", action="store_const", default=logging.INFO, const=logging.DEBUG, help="be more verbose")
p.add_argument("file", metavar="FILE", type=argparse.FileType("rb"), help="Input file")
args = p.parse_args()

logging.basicConfig(format="[%(asctime)s] %(levelname)s: %(message)s", level=args.verbose)

png = PNG.load(args.file.read(), ignore_errors=args.ignore_errors)

print(png)
for chunk in png.chunks:
	print(">", chunk)