def _glowicon_image_argb(self, imagedata, width, height, dark):
        from fsui.qt import QColor, QImage, QPoint, QSize

        # print(repr(imagedata[:16]))
        # print(len(imagedata))

        zlibdata = imagedata[10:]
        data = zlib.decompress(zlibdata)
        offset = 0

        image = QImage(QSize(width, height), QImage.Format_RGBA8888)
        for y in range(height):
            for x in range(width):
                color = QColor(
                    data[offset + 1],
                    data[offset + 2],
                    data[offset + 3],
                    data[offset + 0],
                )
                image.setPixelColor(QPoint(x, y), color)
                offset += 4

        if dark:
            print("FIXME: Make dark version")

        return ShellIconImage(image)
    def resource_qt_image(self, resource):
        from fsui.qt import QImage

        stream = self.stream(resource)
        im = QImage()
        im.loadFromData(stream.read())
        return im
Example #3
0
def load_image(relative_path):
    path = ""
    try:
        if relative_path.startswith("sha1:"):
            sha1 = relative_path[5:]
            path = get_file_for_sha1(sha1)
        else:
            path = relative_path

        if relative_path in error_set:
            return None, (0, 0)

        if hasattr(path, "read"):
            im = QImage()
            im.loadFromData(path.read())
        else:
            if not os.path.exists(path):
                return None, (0, 0)
            im = QImage(path)
        if im.format() != QImage.Format_ARGB32:
            im = im.convertToFormat(QImage.Format_ARGB32)
        bits = im.bits()
        try:
            pixels = bits.tobytes()
        except AttributeError:
            bits.setsize(im.byteCount())
            pixels = bytes(bits)
        return pixels, (im.width(), im.height())

    except Exception as e:
        print("[IMAGES] Error loading",
              repr(relative_path), repr(path), repr(e))
        error_set.add(relative_path)
        return None, (0, 0)
Example #4
0
    def resource_qt_image(self, resource):
        from fsui.qt import QImage

        stream = self.stream(resource)
        im = QImage()
        im.loadFromData(stream.read())
        return im
Example #5
0
    def __init__(self, name="", object=None):
        if object:
            self.qimage = object
        else:
            self.qimage = QImage()

            if hasattr(name, "read"):
                self.qimage.loadFromData(name.read())
            elif name.startswith("pkg://"):
                parts = name.split("/", 3)
                stream = Resources(parts[2]).stream(parts[3])
                self.qimage.loadFromData(stream.read())
            else:
                index = name.find(":")
                if index > 1:
                    package, file_ = name.split(":", 1)
                    stream = Resources(package).stream(file_)
                    self.qimage.loadFromData(stream.read())
                else:
                    print("loading image from", name)
                    self.qimage.load(name)
Example #6
0
    def render(self, text, _, color):
        if self.font is None:
            return "", (0, 0)

        fm = QFontMetrics(self.font)
        rect = fm.boundingRect(text)
        im = QImage(
            rect.x() + rect.width(),
            rect.height(),
            QImage.Format_ARGB32_Premultiplied,
        )
        im.fill(QColor(0, 0, 0, 0))
        painter = QPainter()
        painter.begin(im)
        painter.setPen(QPen(QColor(*color)))
        painter.setFont(self.font)
        painter.drawText(QPoint(0 - rect.x(), 0 - rect.y()), text)
        painter.end()

        bits = im.bits()
        try:
            pixels = bits.tobytes()
        except AttributeError:
            bits.setsize(im.byteCount())
            pixels = bytes(bits)
        return pixels, (rect.x() + rect.width(), rect.height())
Example #7
0
    def __init__(self, name="", object=None):
        if object:
            self.qimage = object
        else:
            self.qimage = QImage()

            if hasattr(name, "read"):
                self.qimage.loadFromData(name.read())
            elif name.startswith("pkg://"):
                parts = name.split("/", 3)
                stream = Resources(parts[2]).stream(parts[3])
                self.qimage.loadFromData(stream.read())
            else:
                index = name.find(":")
                if index > 1:
                    package, file_ = name.split(":", 1)
                    stream = Resources(package).stream(file_)
                    self.qimage.loadFromData(stream.read())
                else:
                    print("loading image from", name)
                    self.qimage.load(name)
    def _image(self, info):
        from fsui.qt import QColor, QImage, QPoint, QSize

        # width = self.uint16(offset + 4)
        # height = self.uint16(offset + 6)
        # bitdepth = self.uint16(offset + 8)
        # has_imagedata = self.uint32(offset + 10)

        if not "width" in info:
            return self._missing_icon()

        width = info["width"]
        height = info["height"]
        bitdepth = info["bitdepth"]
        data = info["data"]

        pitch = ((width + 15) >> 4) << 1
        planebytesize = pitch * height
        planes = []
        for i in range(bitdepth):
            planes.append(data[planebytesize * i : planebytesize * (i + 1)])

        height_factor = 1
        image = QImage(
            QSize(width, height * height_factor), QImage.Format_RGBA8888
        )

        # image.fill(0xFFFFFFFF)

        for y in range(height):
            for x in range(width):
                value = 0
                bytenum = y * pitch + x // 8
                bitnum = 7 - x % 8
                for plane in range(bitdepth):
                    value = (
                        value | (planes[plane][bytenum] >> bitnum & 1) << plane
                    )
                a = 0xFF
                if value == 0:
                    rgb = 0x959595
                    a = 0x00
                elif value == 1:
                    rgb = 0x000000
                elif value == 2:
                    rgb = 0xFFFFFF
                elif value == 3:
                    rgb = 0x3B67A2
                elif value == 4:
                    rgb = 0x7B7B7B
                elif value == 5:
                    rgb = 0xAFAFAF
                elif value == 6:
                    rgb = 0xAA907C
                elif value == 7:
                    rgb = 0xFFA997
                else:
                    # raise Exception("Unsupported color")
                    print(value)
                    color = 0xFF0000
                color = QColor(rgb >> 16, (rgb >> 8) & 0xFF, rgb & 0xFF, a)
                # if height_factor == 2:
                #     image.setPixelColor(QPoint(x, y * 2), color)
                #     image.setPixelColor(QPoint(x, y * 2 + 1), color)
                # else:
                image.setPixelColor(QPoint(x, y), color)

        return ShellIconImage(image)
    def _missing_icon(self):
        from fsui.qt import QImage, QSize

        return Image(qimage=QImage(QSize(1, 1), QImage.Format_RGBA8888))
    def _glowicon_image_imag(self, data, width, height, dark):
        from fsui.qt import QColor, QImage, QPoint, QSize

        transparent_color = data[0]
        num_colors = data[1] + 1
        flags = data[2]
        transparency = flags & 1 != 0
        has_palette = flags & 2 != 0
        compressed = data[3] != 0
        compressed_palette = data[4] != 0
        bitdepth = data[5]
        image_bytes = data[6] * 256 + data[7] + 1
        palette_bytes = data[8] * 256 + data[9] + 1

        print("transparent_color:", transparent_color)
        print("num colors:", num_colors)
        print("flags:", flags)
        print("- transparency:", transparency)
        print("- has_palette:", has_palette)
        print("compression:", compressed)
        print("palette compression:", compressed_palette)
        print("bit depth:", bitdepth)
        print("image bytes:", image_bytes)
        print("palette bytes:", palette_bytes)

        if not transparency:
            transparent_color = -1

        image = QImage(QSize(width, height), QImage.Format_RGBA8888)
        image.fill(0xFFFFFFFF)

        palette = []

        class ParseData:
            bits = []
            bitdepth = 0
            offset = 0
            # line = b""
            palette = True
            compressed = False
            color = []
            done = False
            x = 0
            y = 0
            copy = 0
            produce = 0

        parsedata = ParseData()
        parsedata.offset = 10 + image_bytes
        parsedata.end = 10 + image_bytes + palette_bytes
        parsedata.compressed = compressed_palette
        parsedata.palette = True
        parsedata.bitdepth = 8

        # parsedata.data = data
        # parsedata.ly = 0
        # parsedata.lx = 5
        # parsedata.line = line

        def pushentry(value):
            if parsedata.palette:
                parsedata.color.append(value)
                if len(parsedata.color) == 3:
                    # pylint: disable=unbalanced-tuple-unpacking
                    r, g, b = parsedata.color
                    a = 0xFF
                    print(f"PALETTE{len(palette):02d} 0x{r:02x}{g:02x}{b:02x}")
                    if dark:
                        palette.append(QColor(r * 0.66, g * 0.66, b * 0.66, a))
                    else:
                        palette.append(QColor(r, g, b, a))
                    parsedata.color = []
                # FIXME: More efficient
                # parsedata.bits = parsedata.bits[8:]
                if parsedata.palette and len(palette) >= num_colors:
                    parsedata.palette = False
            elif parsedata.done:
                pass
            else:
                palette_index = value
                # FIXME: Maybe only subtract 1 etc when transparency is True
                # print("palette", palette_index)
                # FIXME: Transparency... correct?
                if palette_index == transparent_color:
                    color = QColor(0x00, 0x00, 0x00, 0x00)
                elif palette_index >= len(palette):
                    color = QColor(0xFF, 0x00, 0x00, 0xFF)
                    print("WARNING, palette_index is", palette_index)
                else:
                    color = palette[palette_index]
                image.setPixelColor(QPoint(parsedata.x, parsedata.y), color)
                # FIXME: More efficient
                # parsedata.bits = parsedata.bits[bitdepth:]
                parsedata.x += 1
                if parsedata.x == width:
                    parsedata.y += 1
                    parsedata.x = 0
                    if parsedata.y == height:
                        parsedata.done = True

        def pushbit(bit):
            parsedata.bits.append(bit)

            if parsedata.produce:
                if len(parsedata.bits) == parsedata.bitdepth:
                    value = bits_to_value(parsedata.bits)
                    for _i in range(parsedata.produce):
                        pushentry(value)
                    parsedata.produce = 0
                    parsedata.bits.clear()

            elif parsedata.copy:
                if len(parsedata.bits) == parsedata.bitdepth:
                    pushentry(bits_to_value(parsedata.bits))
                    parsedata.copy -= 1
                    parsedata.bits.clear()

            elif parsedata.compressed:
                if len(parsedata.bits) == 8:
                    value = bits_to_value(parsedata.bits)
                    if value <= 0x7F:
                        parsedata.copy = value + 1
                    elif value == 0x80:
                        pass
                    else:
                        parsedata.produce = 256 - value + 1
                    parsedata.bits.clear()

            else:
                if len(parsedata.bits) == 8:
                    value = bits_to_value(parsedata.bits[: parsedata.bitdepth])
                    pushentry(value)
                    parsedata.bits.clear()

            # if parsedata.palette:
            #     if len(parsedata.bits) == 8:
            #         parsedata.color.append(bits_to_value(parsedata.bits[0:8]))
            #         if len(parsedata.color) == 3:
            #             # pylint: disable=unbalanced-tuple-unpacking
            #             r, g, b = parsedata.color
            #             a = 0xFF
            #             print(
            #                 f"PALETTE{len(palette):02d} 0x{r:02x}{g:02x}{b:02x}"
            #             )
            #             if dark:
            #                 palette.append(
            #                     QColor(r * 0.66, g * 0.66, b * 0.66, a)
            #                 )
            #             else:
            #                 palette.append(QColor(r, g, b, a))
            #             parsedata.color = []
            #         # FIXME: More efficient
            #         parsedata.bits = parsedata.bits[8:]

            #         if parsedata.palette and len(palette) >= num_colors:
            #             parsedata.palette = False
            # elif parsedata.done:
            #     pass
            # else:
            #     # print("x")
            #     if len(parsedata.bits) == bitdepth:
            #         palette_index = bits_to_value(parsedata.bits[0:bitdepth])
            #         # FIXME: Maybe only subtract 1 etc when transparency is True
            #         # print("palette", palette_index)
            #         # FIXME: Transparency... correct?
            #         if palette_index == 0 and transparency:
            #             color = QColor(0x00, 0x00, 0x00, 0x00)
            #         elif palette_index >= len(palette):
            #             color = QColor(0xFF, 0x00, 0x00, 0xFF)
            #             print("WARNING, palette_index is", palette_index)
            #         else:
            #             color = palette[palette_index]
            #         image.setPixelColor(
            #             QPoint(parsedata.x, parsedata.y), color
            #         )
            #         # FIXME: More efficient
            #         parsedata.bits = parsedata.bits[bitdepth:]
            #         parsedata.x += 1
            #         if parsedata.x == width:
            #             parsedata.y += 1
            #             parsedata.x = 0
            #             if parsedata.y == height:
            #                 parsedata.done = True

        def pushbyte(value):
            for i in range(8):
                pushbit(value >> (7 - i) & 1)

        # def flush():
        #     print("flushing", len(parsedata.bits), "bits")
        #     parsedata.bits = []

        def dobyte():
            value = data[parsedata.offset]
            # if parsedata.compressed:
            #     # 0x00 .. 0x7F copy the next n entries as they are, where n is "RLE-value"+1
            #     # 0x80         ignore this, do nothing
            #     # 0x81 .. 0xFF produce the next entry n times, where n is 256-"RLE-value"+1
            #     #             (if using signed chars n is "RLE-value"+1)
            #     if parsedata.produce:
            #         for _i in range(parsedata.produce):
            #             pushbyte(value)
            #         parsedata.produce = 0
            #     elif parsedata.copy:
            #         pushbyte(value)
            #         parsedata.copy -= 1
            #     elif value <= 0x7F:
            #         parsedata.copy = value + 1
            #     elif value == 0x80:
            #         pass
            #     else:
            #         parsedata.produce = 256 - value + 1
            # else:
            #     if not parsedata.palette and not parsedata.compressed:
            #         # FIXME: Only push bitdepth bits
            #         raise Exception("TODO: Unsupported")
            #     else:
            #         pushbyte(value)

            pushbyte(value)
            parsedata.offset += 1

        while parsedata.offset < parsedata.end:
            dobyte()
        print(len(parsedata.bits))

        parsedata.offset = 10
        parsedata.end = 10 + image_bytes
        parsedata.compressed = compressed
        parsedata.palette = False
        parsedata.copy = 0
        parsedata.produce = 0
        parsedata.bitdepth = bitdepth

        print(parsedata.offset, parsedata.end)
        while parsedata.offset < parsedata.end:
            dobyte()

        print(width, height)
        print(parsedata.x, parsedata.y)

        # import sys
        # sys.exit(1)
        return ShellIconImage(image)
    def _newicon_image(self, index):
        from fsui.qt import QColor, QImage, QPoint, QSize

        linedata = self._linedata_for_index(index)
        dark = False
        if not linedata:
            if index == 1:
                dark = True
                linedata = self._linedata_for_index(0)
            if not linedata:
                return self._missing_icon()

        # line = strdata[0].encode("ISO-8859-1")
        line = linedata[0]
        if line[0:1] not in [b"B", b"C"]:
            print("WARNING: Newion data does not start with B or C")
        transparency = line[0:1] == b"B"
        width = line[1] - 0x21
        height = line[2] - 0x21
        colors = ((line[3] - 0x21) << 6) + (line[4] - 0x21)
        bitdepth = 1
        while 2 ** bitdepth < colors:
            bitdepth += 1
        print("colors", colors, "=> bitdepth", bitdepth)

        print(width, height, transparency, colors)

        image = QImage(QSize(width, height), QImage.Format_RGBA8888)

        # image.fill(0xFFFFFFFF)

        palette = []

        # offset = 5
        # for i in range(colors):
        #     r = line[offset]
        #     g = line[offset + 1]
        #     b = line[offset + 2]
        #     a = 0xFF
        #     palette.append(QColor(r, g, b, a))
        #     offset += 3
        # print(len(line), "vs", offset)

        # parser = []
        # ly = 0
        # lx = 5

        class ParseData:
            bits = []
            ly = 0
            ly = 0
            line = b""
            palette = True
            color = []
            done = False
            x = 0
            y = 0

        parsedata = ParseData()
        parsedata.ly = 0
        parsedata.lx = 5
        parsedata.line = line

        def pushbit(bit):
            parsedata.bits.append(bit)
            if parsedata.palette:
                if len(parsedata.bits) == 8:
                    # parsedata.color.append(bits_to_value(parsedata.bits[0:8]))
                    parsedata.color.append(bits_to_value(parsedata.bits))
                    # r = bits_to_value(parsedata.bits[0:8])
                    # g = bits_to_value(parsedata.bits[8:16])
                    # b = bits_to_value(parsedata.bits[16:24])
                    if len(parsedata.color) == 3:
                        # pylint: disable=unbalanced-tuple-unpacking
                        r, g, b = parsedata.color
                        a = 0xFF
                        print(
                            f"PALETTE{len(palette):02d} 0x{r:02x}{g:02x}{b:02x}"
                        )
                        if dark:
                            palette.append(
                                QColor(r * 0.67, g * 0.67, b * 0.67, a)
                            )
                        else:
                            palette.append(QColor(r, g, b, a))
                        parsedata.color = []
                    # FIXME: More efficient
                    # parsedata.bits = parsedata.bits[8:]
                    parsedata.bits.clear()

                    # if parsedata.palette and len(palette) >= colors:
                    #     parsedata.palette = False
            elif parsedata.done:
                pass
            else:
                if len(parsedata.bits) == bitdepth:
                    # palette_index = bits_to_value(parsedata.bits[0:bitdepth])
                    palette_index = bits_to_value(parsedata.bits)
                    # FIXME: Maybe only subtract 1 etc when transparency is True
                    # print("palette", palette_index)
                    # FIXME: Transparency... correct?
                    if palette_index == 0 and transparency:
                        color = QColor(0x00, 0x00, 0x00, 0x00)
                    elif palette_index >= len(palette):
                        color = QColor(0xFF, 0x00, 0x00, 0xFF)
                        print("WARNING, palette_index is", palette_index)
                    else:
                        color = palette[palette_index]
                    image.setPixelColor(
                        QPoint(parsedata.x, parsedata.y), color
                    )
                    # FIXME: More efficient
                    # parsedata.bits = parsedata.bits[bitdepth:]
                    parsedata.bits.clear()
                    parsedata.x += 1
                    if parsedata.x == width:
                        parsedata.y += 1
                        parsedata.x = 0
                        if parsedata.y == height:
                            parsedata.done = True

        def flush():
            print("flushing", len(parsedata.bits), "bits")
            parsedata.bits.clear()

        def dobyte():
            val = parsedata.line[parsedata.lx]
            # print(f"in 0x{val:x}")
            val2 = 0
            if val >= 0x20 and val <= 0x6F:
                val2 = val - 0x20
                for i in range(7):
                    pushbit(val2 >> (6 - i) & 1)
            elif val >= 0xA1 and val <= 0xD0:
                val2 = val - 0xA1 + 0x50
                for i in range(7):
                    pushbit(val2 >> (6 - i) & 1)
            elif val >= 0xD1:
                rle = val - 0xD0
                for i in range(rle):
                    for j in range(7):
                        pushbit(0)
                # print("???")
                pass
            else:
                raise Exception("Unexpected newicon byte")
            parsedata.lx += 1
            # print("lx is now", parsedata.lx)
            if parsedata.lx == len(parsedata.line):
                flush()
                parsedata.lx = 0
                parsedata.ly += 1
                if parsedata.ly < len(linedata):
                    parsedata.line = linedata[parsedata.ly]
                else:
                    # We are done
                    parsedata.line = None

                if parsedata.palette and len(palette) >= colors:
                    print("Done parsing palette")
                    if len(palette) > colors:
                        print("WARNING: More colors than expected??")
                    parsedata.palette = False

        # while parsedata.lx < len(parsedata.line):
        #     dobyte()
        while parsedata.ly < len(linedata) and parsedata.lx < len(
            parsedata.line
        ):
            dobyte()
        print(len(parsedata.bits))

        print("x", parsedata.x, "y", parsedata.y)
        if parsedata != height and parsedata.x != 0:
            print("WARNING: Did not decode image according to size")
        # assert parsedata.y == height
        # assert parsedata.x == 0

        # import sys
        # sys.exit(1)

        # pixels = []
        # ly = 1
        # lx = 0
        # line = linedata[ly]
        # while True:
        #     val = line[lx]
        #     val2 = 0
        #     if val >= 0x20 and val <= 0x6F:
        #         val2 = val - 0x20
        #     elif val >= 0xA1 and val <= 0xD0:
        #         val2 = val - 0xA1 + 0x50
        #     else:
        #         print(f"0x{val:x}")
        #         raise Exception("???")

        # for y in range(height):
        #     for x in range(width):
        #         # image.setPixelColor(QPoint(x, y * 2 + 1), color)
        #         pass

        # import sys
        # sys.exit(1)

        return ShellIconImage(image)
Example #12
0
 def qimage(self, size):
     stream = self.stream_for_size(size)
     qimage = QImage()
     qimage.loadFromData(stream.read())
     return qimage
Example #13
0
    def create_retroarch_layout(self):
        if self.stretching() == self.STRETCH_FILL_SCREEN or not self.bezel():
            return
        if not self.use_fullscreen():
            return

        # FIXME: file cmp?
        paths = self.prepare_emulator_skin()
        print(paths)

        # FIXME: SUPPORT frame = 0 ( bezel = 0) option

        # FIXME: With no bezel, we should still use a black bezel to
        # hide screen stretching

        screen_width, screen_height = self.screen_size()
        # dst_x = 0
        dst_y = 0
        # dst_w = 0
        # dst_w = 160
        dst_h = screen_height

        # Bezel size is normalized against 1080 (height)
        scale = screen_height / 1080
        # Bezel width: 160
        dst_w = round(160 * scale)

        game_x, game_y, game_w, game_h = self.display_rect_fullscreen()

        from fsui.qt import Qt, QImage, QPainter, QRect, QSize

        image = QImage(
            QSize(screen_width, screen_height), QImage.Format_RGBA8888
        )
        image.fill(Qt.transparent)
        # painter = image.paintEngine()
        painter = QPainter(image)

        dst_x = game_x - dst_w
        left = QImage(paths["left"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), left)

        dst_x = game_x + game_w
        right = QImage(paths["right"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), right)
        painter.end()

        overlay_png_file = self.temp_file("overlay.png").path
        image.save(overlay_png_file)

        # noinspection SpellCheckingInspection
        overlay_config = """overlays = 1
overlay0_overlay = {overlay}
overlay0_full_screen = true
overlay0_rect = "0.0,0.0,1.0,1.0"
overlay0_descs = 0
""".format(
            overlay=overlay_png_file
        )
        #         overlay_config = (
        #             """overlays = 2
        # overlay0_overlay = {left}
        # overlay0_full_screen = true
        # overlay0_rect = "0.0,0.0,0.12,1.0"
        # overlay0_descs = 0
        # overlay1_overlay = {right}
        # overlay1_full_screen = true
        # overlay1_rect = "0.8,0.0,0.2,1.0"
        # overlay1_descs = 0
        #
        # """.format(left=paths["left"], right=paths["right"]))
        overlay_config_file = self.temp_file("overlay.cfg")
        with open(overlay_config_file.path, "w") as f:
            f.write(overlay_config)
        return overlay_config_file.path
Example #14
0
class Image(object):

    NEAREST = 0

    def __init__(self, name="", object=None):
        if object:
            self.qimage = object
        else:
            self.qimage = QImage()

            if hasattr(name, "read"):
                self.qimage.loadFromData(name.read())
            elif name.startswith("pkg://"):
                parts = name.split("/", 3)
                stream = Resources(parts[2]).stream(parts[3])
                self.qimage.loadFromData(stream.read())
            else:
                index = name.find(":")
                if index > 1:
                    package, file_ = name.split(":", 1)
                    stream = Resources(package).stream(file_)
                    self.qimage.loadFromData(stream.read())
                else:
                    print("loading image from", name)
                    self.qimage.load(name)
            # self._bitmap = None

    @property
    def size(self):
        return self.qimage.width(), self.qimage.height()

    def width(self):
        return self.qimage.width()

    def height(self):
        return self.qimage.height()

    @property
    def qpixmap(self):
        return QPixmap(self.qimage)

    @property
    def qicon(self):
        return QIcon(QPixmap(self.qimage))

    # @property
    # def bitmap(self):
    #     if self._bitmap is None:
    #         self._bitmap = wx.BitmapFromImage(self.qimage)
    #     return self._bitmap

    def grey_scale(self):
        # return Image(object=self.qimage.convertToFormat(
        #     QImage.Format_ARGB32, Qt.AutoOnly))
        copy = self.qimage.convertToFormat(QImage.Format_ARGB32, Qt.AutoColor)
        # copy = self.qimage.copy(0, 0, *self.size)

        # WARNING: this is presumably a bit slow...
        for y in range(self.size[1]):
            for x in range(self.size[0]):
                p = copy.pixel(x, y)

                # RGBA
                # r = (p & 0xff000000) >> 24
                # g = (p & 0x00ff0000) >> 16
                # b = (p & 0x0000ff00) >> 8
                # a = p & 0x000000ff
                # # v = (r + g + b) // 3
                # v = int(r * 0.299 + g * 0.587 + b * 0.114)
                # p = v << 24 | v << 16 | v << 8 | a

                # ARGB
                a = (p & 0xFF000000) >> 24
                r = (p & 0x00FF0000) >> 16
                g = (p & 0x0000FF00) >> 8
                b = p & 0x000000FF
                # v = (r + g + b) // 3
                v = int(r * 0.299 + g * 0.587 + b * 0.114)
                p = a << 24 | v << 16 | v << 8 | v

                copy.setPixel(x, y, p)
        return Image(object=copy)

    def resize(self, size, filter=1):
        if size == self.size:
            return
        if filter:
            q = Qt.SmoothTransformation
        else:
            q = Qt.FastTransformation
        self.qimage = self.qimage.scaled(size[0], size[1],
                                         Qt.IgnoreAspectRatio, q)
        # self._bitmap = None

    def save(self, path):
        self.qimage.save(path)
    def _pngicon_image(self, index):
        print("_pngicon_image", index)
        from fsui.qt import QImage, QPoint

        dark = False
        if index == 1 and len(self.parser.png_images) == 1:
            data = self.parser.png_images[0]
            dark = True
        elif index < len(self.parser.png_images):
            data = self.parser.png_images[index]
        else:
            return self._missing_icon()
        image = QImage()
        # print("load from data", data)
        image.loadFromData(data, "PNG")
        print(image.size().width(), image.size().height())
        # FIXME: dark
        if dark:
            for y in range(image.height()):
                for x in range(image.width()):
                    point = QPoint(x, y)
                    color = image.pixelColor(point)
                    color.setRed(color.red() * 0.67)
                    color.setGreen(color.green() * 0.67)
                    color.setBlue(color.blue() * 0.67)
                    image.setPixelColor(point, color)

        return ShellIconImage(image)
    def create_retroarch_layout(self):
        if self.stretching() == self.STRETCH_FILL_SCREEN or not self.bezel():
            return
        if not self.use_fullscreen():
            return

        # FIXME: file cmp?
        paths = self.prepare_emulator_skin()
        print(paths)

        # FIXME: SUPPORT frame = 0 ( bezel = 0) option

        # FIXME: With no bezel, we should still use a black bezel to
        # hide screen stretching

        screen_width, screen_height = self.screen_size()
        # dst_x = 0
        dst_y = 0
        # dst_w = 0
        # dst_w = 160
        dst_h = screen_height

        # Bezel size is normalized against 1080 (height)
        scale = screen_height / 1080
        # Bezel width: 160
        dst_w = round(160 * scale)

        game_x, game_y, game_w, game_h = self.display_rect_fullscreen()

        from fsui.qt import Qt, QImage, QPainter, QRect, QSize

        image = QImage(QSize(screen_width, screen_height),
                       QImage.Format_RGBA8888)
        image.fill(Qt.transparent)
        # painter = image.paintEngine()
        painter = QPainter(image)

        dst_x = game_x - dst_w
        left = QImage(paths["left"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), left)

        dst_x = game_x + game_w
        right = QImage(paths["right"])
        painter.drawImage(QRect(dst_x, dst_y, dst_w, dst_h), right)
        painter.end()

        overlay_png_file = self.temp_file("overlay.png").path
        image.save(overlay_png_file)

        # noinspection SpellCheckingInspection
        overlay_config = """overlays = 1
overlay0_overlay = {overlay}
overlay0_full_screen = true
overlay0_rect = "0.0,0.0,1.0,1.0"
overlay0_descs = 0
""".format(overlay=overlay_png_file)
        #         overlay_config = (
        #             """overlays = 2
        # overlay0_overlay = {left}
        # overlay0_full_screen = true
        # overlay0_rect = "0.0,0.0,0.12,1.0"
        # overlay0_descs = 0
        # overlay1_overlay = {right}
        # overlay1_full_screen = true
        # overlay1_rect = "0.8,0.0,0.2,1.0"
        # overlay1_descs = 0
        #
        # """.format(left=paths["left"], right=paths["right"]))
        overlay_config_file = self.temp_file("overlay.cfg")
        with open(overlay_config_file.path, "w") as f:
            f.write(overlay_config)
        return overlay_config_file.path
Example #17
0
def load_image(relative_path):
    path = ""
    try:
        if relative_path.startswith("sha1:"):
            sha1 = relative_path[5:]
            path = get_file_for_sha1(sha1)
        else:
            path = relative_path

        if relative_path in error_set:
            return None, (0, 0)

        if hasattr(path, "read"):
            im = QImage()
            im.loadFromData(path.read())
        else:
            if not os.path.exists(path):
                return None, (0, 0)
            im = QImage(path)
        if im.format() != QImage.Format_ARGB32:
            im = im.convertToFormat(QImage.Format_ARGB32)
        bits = im.bits()
        try:
            pixels = bits.tobytes()
        except AttributeError:
            bits.setsize(im.byteCount())
            pixels = bytes(bits)
        return pixels, (im.width(), im.height())

    except Exception as e:
        print(
            "[IMAGES] Error loading", repr(relative_path), repr(path), repr(e)
        )
        error_set.add(relative_path)
        return None, (0, 0)
Example #18
0
class Image(object):

    NEAREST = 0

    def __init__(self, name="", object=None):
        if object:
            self.qimage = object
        else:
            self.qimage = QImage()

            if hasattr(name, "read"):
                self.qimage.loadFromData(name.read())
            elif name.startswith("pkg://"):
                parts = name.split("/", 3)
                stream = Resources(parts[2]).stream(parts[3])
                self.qimage.loadFromData(stream.read())
            else:
                index = name.find(":")
                if index > 1:
                    package, file_ = name.split(":", 1)
                    stream = Resources(package).stream(file_)
                    self.qimage.loadFromData(stream.read())
                else:
                    print("loading image from", name)
                    self.qimage.load(name)
            # self._bitmap = None

    @property
    def size(self):
        return self.qimage.width(), self.qimage.height()

    def width(self):
        return self.qimage.width()

    def height(self):
        return self.qimage.height()

    @property
    def qpixmap(self):
        return QPixmap(self.qimage)

    @property
    def qicon(self):
        return QIcon(QPixmap(self.qimage))

    # @property
    # def bitmap(self):
    #     if self._bitmap is None:
    #         self._bitmap = wx.BitmapFromImage(self.qimage)
    #     return self._bitmap

    def grey_scale(self):
        # return Image(object=self.qimage.convertToFormat(
        #     QImage.Format_ARGB32, Qt.AutoOnly))
        copy = self.qimage.convertToFormat(QImage.Format_ARGB32, Qt.AutoColor)
        # copy = self.qimage.copy(0, 0, *self.size)

        # WARNING: this is presumably a bit slow...
        for y in range(self.size[1]):
            for x in range(self.size[0]):
                p = copy.pixel(x, y)

                # RGBA
                # r = (p & 0xff000000) >> 24
                # g = (p & 0x00ff0000) >> 16
                # b = (p & 0x0000ff00) >> 8
                # a = p & 0x000000ff
                # # v = (r + g + b) // 3
                # v = int(r * 0.299 + g * 0.587 + b * 0.114)
                # p = v << 24 | v << 16 | v << 8 | a

                # ARGB
                a = (p & 0xFF000000) >> 24
                r = (p & 0x00FF0000) >> 16
                g = (p & 0x0000FF00) >> 8
                b = p & 0x000000FF
                # v = (r + g + b) // 3
                v = int(r * 0.299 + g * 0.587 + b * 0.114)
                p = a << 24 | v << 16 | v << 8 | v

                copy.setPixel(x, y, p)
        return Image(object=copy)

    def resize(self, size, filter=1):
        if size == self.size:
            return
        if filter:
            q = Qt.SmoothTransformation
        else:
            q = Qt.FastTransformation
        self.qimage = self.qimage.scaled(
            size[0], size[1], Qt.IgnoreAspectRatio, q
        )