Ejemplo n.º 1
0
 def _write_selection_to_output_file(self, index: int, selection: Selection,
                                     progress_step_size: float):
     """
     Creates a new image file and writes the content of the given selection to disk.
     :param index: The index of this selection. This is used to build increasing file numbers for the output file.
     :param selection: The Selection in progress
     :param progress_step_size: Float giving the current progress step size per file in percent. Used for progress
     notifications and logging purposes.
     :return:
     """
     extract = self.image_data.copy(selection.as_qrect)
     self.write_output_progress.emit(
         int((2 * index - 1) * progress_step_size))
     logger.debug(
         f"Extracted selection. Progress: {(2*index-1)*progress_step_size:2.2f}%"
     )
     writer = QImageWriter(self._get_output_file_name(index))
     if writer.canWrite():
         writer.write(extract)
         logger.debug(
             f"Written extracted selection to disk. Progress: {(2*index)*progress_step_size:2.2f}%"
         )
     else:
         logger.warning(
             f"Image data can not be written! Offending File: {writer.fileName()}"
         )
     self.write_output_progress.emit(int((2 * index) * progress_step_size))
Ejemplo n.º 2
0
 def saveImage(self, dirpath):
     img = FlowBoardPainter.renderImage(self._board, self._solver)
     filename = hex(abs(self._solver.stateHash()))[2:] + '.png'
     writer = QImageWriter(path.join(dirpath, filename))
     writer.setFormat('png')
     if not writer.write(img):
         raise Exception(writer.errorString())
Ejemplo n.º 3
0
def image_to_data(img,
                  compression_quality=95,
                  fmt='JPEG',
                  png_compression_level=9,
                  jpeg_optimized=True,
                  jpeg_progressive=False):
    '''
    Serialize image to bytestring in the specified format.

    :param compression_quality: is for JPEG and goes from 0 to 100. 100 being lowest compression, highest image quality
    :param png_compression_level: is for PNG and goes from 0-9. 9 being highest compression.
    :param jpeg_optimized: Turns on the 'optimize' option for libjpeg which losslessly reduce file size
    :param jpeg_progressive: Turns on the 'progressive scan' option for libjpeg which allows JPEG images to be downloaded in streaming fashion
    '''
    fmt = fmt.upper()
    ba = QByteArray()
    buf = QBuffer(ba)
    buf.open(QBuffer.WriteOnly)
    if fmt == 'GIF':
        w = QImageWriter(buf, b'PNG')
        w.setQuality(90)
        if not w.write(img):
            raise ValueError('Failed to export image as ' + fmt +
                             ' with error: ' + w.errorString())
        from PIL import Image
        im = Image.open(BytesIO(ba.data()))
        buf = BytesIO()
        im.save(buf, 'gif')
        return buf.getvalue()
    is_jpeg = fmt in ('JPG', 'JPEG')
    w = QImageWriter(buf, fmt.encode('ascii'))
    if is_jpeg:
        if img.hasAlphaChannel():
            img = blend_image(img)
        # QImageWriter only gained the following options in Qt 5.5
        if jpeg_optimized:
            w.setOptimizedWrite(True)
        if jpeg_progressive:
            w.setProgressiveScanWrite(True)
        w.setQuality(compression_quality)
    elif fmt == 'PNG':
        cl = min(9, max(0, png_compression_level))
        w.setQuality(10 * (9 - cl))
    if not w.write(img):
        raise ValueError('Failed to export image as ' + fmt + ' with error: ' +
                         w.errorString())
    return ba.data()
Ejemplo n.º 4
0
 def render_png(self, svg_data: str, *, compression=40) -> bytes:
     """ Rasterize an SVG image to PNG format and return the raw bytes. """
     im = self._render(svg_data)
     buf = QBuffer()
     writer = QImageWriter(buf, b'PNG')
     writer.setCompression(compression)
     writer.write(im)
     return buf.data().data()
Ejemplo n.º 5
0
def tmpimage(tmpdir, qtbot):
    """Create an image to work with."""
    path = str(tmpdir.join("any_image.png"))
    width = 10
    height = 10
    pm = QPixmap(width, height)
    qtbot.addWidget(pm)
    writer = QImageWriter(path)
    assert writer.write(pm.toImage())
    return path
Ejemplo n.º 6
0
    def render(self, mapFileName, imageFileName):
        map = None
        renderer = None
        reader = MapReader()
        map = reader.readMap(mapFileName)
        if (not map):
            qWarning("Error while reading " + mapFileName + ":\n" +
                     reader.errorString())
            return 1

        x = map.orientation()
        if x == Map.Orientation.Isometric:
            renderer = IsometricRenderer(map)
        elif x == Map.Orientation.Staggered:
            renderer = StaggeredRenderer(map)
        elif x == Map.Orientation.Hexagonal:
            renderer = HexagonalRenderer(map)
        else:
            renderer = OrthogonalRenderer(map)

        if (self.mTileSize > 0):
            xScale = self.mTileSize / map.tileWidth()
            yScale = self.mTileSize / map.tileHeight()
        else:
            xScale = yScale = self.mScale

        mapSize = renderer.mapSize()
        margins = map.computeLayerOffsetMargins()
        mapSize.setWidth(mapSize.width() + margins.left() + margins.right())
        mapSize.setHeight(mapSize.height() + margins.top() + margins.bottom())

        mapSize.setWidth(mapSize.width() * xScale)
        mapSize.setHeight(mapSize.height() * yScale)
        image = QImage(mapSize, QImage.Format_ARGB32)
        image.fill(Qt.transparent)
        painter = QPainter(image)
        if (xScale != 1.0 or yScale != 1.0):
            if (self.mUseAntiAliasing):
                painter.setRenderHints(QPainter.SmoothPixmapTransform
                                       | QPainter.Antialiasing)

            painter.setTransform(QTransform.fromScale(xScale, yScale))

        painter.translate(margins.left(), margins.top())

        # Perform a similar rendering than found in exportasimagedialog.py
        for layer in map.layers():
            if (not self.shouldDrawLayer(layer)):
                continue
            painter.setOpacity(layer.opacity())
            painter.translate(layer.offset())
            tileLayer = layer
            imageLayer = layer
            tp = type(layer)
            if tp == TileLayer:
                renderer.drawTileLayer(painter, tileLayer)
            elif tp == ImageLayer:
                renderer.drawImageLayer(painter, imageLayer)
            painter.translate(-layer.offset())
        painter.end()

        # Save image
        imageWriter = QImageWriter(imageFileName)
        if (not imageWriter.write(image)):
            qWarning("Error while writing " + imageFileName + ": " +
                     imageWriter.errorString())
            return 1

        return 0
    def exportGeorefRaster(self, layer, rasterPath, isPutRotationInWorldFile,
                           isExportOnlyWorldFile):
        baseRasterFilePath, _ = os.path.splitext(rasterPath)
        # suppose supported format already checked
        rasterFormat = utils.imageFormat(rasterPath)

        try:
            originalWidth = layer.image.width()
            originalHeight = layer.image.height()
            radRotation = layer.rotation * math.pi / 180

            if isPutRotationInWorldFile or isExportOnlyWorldFile:
                # keep the image as is and put all transformation params
                # in world file
                img = layer.image

                a = layer.xScale * math.cos(radRotation)
                # sin instead of -sin because angle in CW
                b = -layer.yScale * math.sin(radRotation)
                d = layer.xScale * -math.sin(radRotation)
                e = -layer.yScale * math.cos(radRotation)
                c = layer.center.x() - (a * (originalWidth - 1) / 2 + b *
                                        (originalHeight - 1) / 2)
                f = layer.center.y() - (d * (originalWidth - 1) / 2 + e *
                                        (originalHeight - 1) / 2)

            else:
                # transform the image with rotation and scaling between the
                # axes
                # maintain at least the original resolution of the raster
                ratio = layer.xScale / layer.yScale
                if ratio > 1:
                    # increase x
                    scaleX = ratio
                    scaleY = 1
                else:
                    # increase y
                    scaleX = 1
                    scaleY = 1.0 / ratio

                width = abs(
                    scaleX * originalWidth * math.cos(radRotation)) + abs(
                        scaleY * originalHeight * math.sin(radRotation))
                height = abs(
                    scaleX * originalWidth * math.sin(radRotation)) + abs(
                        scaleY * originalHeight * math.cos(radRotation))

                qDebug("wh %f,%f" % (width, height))

                img = QImage(QSize(math.ceil(width), math.ceil(height)),
                             QImage.Format_ARGB32)
                # transparent background
                img.fill(QColor(0, 0, 0, 0))

                painter = QPainter(img)
                painter.setRenderHint(QPainter.Antialiasing, True)
                # painter.setRenderHint(QPainter.SmoothPixmapTransform, True)

                rect = QRectF(
                    QPointF(-layer.image.width() / 2.0,
                            -layer.image.height() / 2.0),
                    QPointF(layer.image.width() / 2.0,
                            layer.image.height() / 2.0),
                )

                painter.translate(QPointF(width / 2.0, height / 2.0))
                painter.rotate(layer.rotation)
                painter.scale(scaleX, scaleY)
                painter.drawImage(rect, layer.image)
                painter.end()

                extent = layer.extent()
                a = extent.width() / width
                e = -extent.height() / height
                # 2nd term because (0,0) of world file is on center of upper
                # left pixel instead of upper left corner of that pixel
                c = extent.xMinimum() + a / 2
                f = extent.yMaximum() + e / 2
                b = d = 0.0

            if not isExportOnlyWorldFile:
                # export image
                if rasterFormat == "tif":
                    writer = QImageWriter()
                    # use LZW compression for tiff
                    # useful for scanned documents (mostly white)
                    writer.setCompression(1)
                    writer.setFormat(b"TIFF")
                    writer.setFileName(rasterPath)
                    writer.write(img)
                else:
                    img.save(rasterPath, rasterFormat)

            worldFilePath = baseRasterFilePath + "."
            if rasterFormat == "jpg":
                worldFilePath += "jgw"
            elif rasterFormat == "png":
                worldFilePath += "pgw"
            elif rasterFormat == "bmp":
                worldFilePath += "bpw"
            elif rasterFormat == "tif":
                worldFilePath += "tfw"

            with open(worldFilePath, "w") as writer:
                # order is as described at
                # http://webhelp.esri.com/arcims/9.3/General/topics/author_world_files.htm
                writer.write("%.13f\n%.13f\n%.13f\n%.13f\n%.13f\n%.13f" %
                             (a, d, b, e, c, f))

            crsFilePath = rasterPath + ".aux.xml"
            with open(crsFilePath, "w") as writer:
                writer.write(
                    self.auxContent(
                        self.iface.mapCanvas().mapSettings().destinationCrs()))

            widget = QgsMessageBar.createMessage(
                "Raster Geoferencer", "Raster exported successfully.")
            self.iface.messageBar().pushWidget(widget, Qgis.Info, 2)
        except Exception as ex:
            QgsMessageLog.logMessage(repr(ex))
            widget = QgsMessageBar.createMessage(
                "Raster Geoferencer",
                "There was an error performing this command. "
                "See QGIS Message log for details.",
            )
            self.iface.messageBar().pushWidget(widget, Qgis.Critical, 5)