Beispiel #1
0
 def store_file(self, id, file):
     id = id.replace('/', '_')
     directory = ApplicationData.get('images')
     filename = os.path.join(directory, id + '.png')
     if filename == os.path.normpath(file):
         return self.iconmap.get(id, None)
     makedirs(directory)
     pixmap = QPixmap()
     if file is not None and pixmap.load(file):
         if pixmap.size().width() > self.max_size or pixmap.size().height() > self.max_size:
             pixmap = pixmap.scaled(self.max_size, self.max_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
         buffer = QBuffer()
         pixmap.save(buffer, 'png')
         data = str(buffer.data())
         with open(filename, 'wb') as f:
             f.write(data)
         icon = QIcon(pixmap)
         icon.filename = filename
         icon.content = data
         icon.content_type = 'image/png'
     else:
         unlink(filename)
         icon = None
     self.iconmap[id] = icon
     return icon
    def _addIcon(self):
        filter_ = self.tr("Images (*.jpg *.jpeg *.bmp *.png *.tiff *.gif);;"
                          "All files (*.*)")
        fileName, _selectedFilter = QFileDialog.getOpenFileName(self,
                self.tr("Open File"), self.latestDir,
                filter_)
        if fileName:
            file_info = QFileInfo(fileName)
            self.latestDir = file_info.absolutePath()

            image = QImage()
            if image.load(fileName):
                maxWidth = 22
                maxHeight = 15
                if image.width() > maxWidth or image.height() > maxHeight:
                    scaledImage = image.scaled(maxWidth, maxHeight,
                            Qt.KeepAspectRatio, Qt.SmoothTransformation)
                else:
                    scaledImage = image

                ba = QByteArray()
                buffer = QBuffer(ba)
                buffer.open(QIODevice.WriteOnly)
                scaledImage.save(buffer, 'png')

                model = self.model()
                index = model.index(self.selectedIndex().row(), model.fieldIndex('icon'))
                model.setData(index, ba)
Beispiel #3
0
    def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode):
        archive = VirtualFile()
        archive.openStream(stream, "application/x-ufp", OpenMode.WriteOnly)

        #Store the g-code from the scene.
        archive.addContentType(extension = "gcode", mime_type = "text/x-gcode")
        gcode_textio = StringIO() #We have to convert the g-code into bytes.
        PluginRegistry.getInstance().getPluginObject("GCodeWriter").write(gcode_textio, None)
        gcode = archive.getStream("/3D/model.gcode")
        gcode.write(gcode_textio.getvalue().encode("UTF-8"))
        archive.addRelation(virtual_path = "/3D/model.gcode", relation_type = "http://schemas.ultimaker.org/package/2018/relationships/gcode")

        #Store the thumbnail.
        if self._snapshot:
            archive.addContentType(extension = "png", mime_type = "image/png")
            thumbnail = archive.getStream("/Metadata/thumbnail.png")

            thumbnail_buffer = QBuffer()
            thumbnail_buffer.open(QBuffer.ReadWrite)
            thumbnail_image = self._snapshot
            thumbnail_image.save(thumbnail_buffer, "PNG")

            thumbnail.write(thumbnail_buffer.data())
            archive.addRelation(virtual_path = "/Metadata/thumbnail.png", relation_type = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail", origin = "/3D/model.gcode")
        else:
            Logger.log("d", "Thumbnail not created, cannot save it")

        archive.close()
        return True
Beispiel #4
0
    def loadFromMemory(self):
        """ This slot function is called in the second Dialog process, when the
        user presses the "Load Image from Shared Memory" button.  First, it
        attaches the process to the shared memory segment created by the first
        Dialog process.  Then it locks the segment for exclusive access, copies
        the image data from the segment into a QBuffer, and streams the QBuffer
        into a QImage.  Then it unlocks the shared memory segment, detaches
        from it, and finally displays the QImage in the Dialog.
        """

        if not self.sharedMemory.attach():
            self.ui.label.setText(
                    "Unable to attach to shared memory segment.\nLoad an "
                    "image first.")
            return
 
        buf = QBuffer()
        ins = QDataStream(buf)
        image = QImage()

        self.sharedMemory.lock()
        buf.setData(self.sharedMemory.constData())
        buf.open(QBuffer.ReadOnly)
        ins >> image
        self.sharedMemory.unlock()
        self.sharedMemory.detach()

        self.ui.label.setPixmap(QPixmap.fromImage(image))
Beispiel #5
0
 def mimeData(self, indexes):
     """
     Public method to return the mime data.
     
     @param indexes list of indexes (QModelIndexList)
     @return mime data (QMimeData)
     """
     from .XbelWriter import XbelWriter
     
     data = QByteArray()
     stream = QDataStream(data, QIODevice.WriteOnly)
     urls = []
     
     for index in indexes:
         if index.column() != 0 or not index.isValid():
             continue
         
         encodedData = QByteArray()
         buffer = QBuffer(encodedData)
         buffer.open(QIODevice.ReadWrite)
         writer = XbelWriter()
         parentNode = self.node(index)
         writer.write(buffer, parentNode)
         stream << encodedData
         urls.append(index.data(self.UrlRole))
     
     mdata = QMimeData()
     mdata.setData(self.MIMETYPE, data)
     mdata.setUrls(urls)
     return mdata
Beispiel #6
0
    def mouseMoveEvent(self, event):
        """ If the mouse moves far enough when the left mouse button is held
            down, start a drag and drop operation.
        """
        if not event.buttons() & Qt.LeftButton:
            return

        if (event.pos() - self.dragStartPosition).manhattanLength() \
             < QApplication.startDragDistance():
            return

        if not self.hasImage:
            return

        drag = QDrag(self)
        mimeData = QMimeData()

        output = QByteArray()
        outputBuffer = QBuffer(output)
        outputBuffer.open(QIODevice.WriteOnly)
        self.imageLabel.pixmap().toImage().save(outputBuffer, 'PNG')
        outputBuffer.close()
        mimeData.setData('image/png', output)

        drag.setMimeData(mimeData)
        drag.setPixmap(self.imageLabel.pixmap().scaled(64, 64, Qt.KeepAspectRatio))
        drag.setHotSpot(QPoint(drag.pixmap().width() / 2,
                                      drag.pixmap().height()))
        drag.start()
Beispiel #7
0
 def dropMimeData(self, data, action, row, column, parent):
     """
     Public method to accept the mime data of a drop action.
     
     @param data reference to the mime data (QMimeData)
     @param action drop action requested (Qt.DropAction)
     @param row row number (integer)
     @param column column number (integer)
     @param parent index of the parent node (QModelIndex)
     @return flag indicating successful acceptance of the data (boolean)
     """
     if action == Qt.IgnoreAction:
         return True
     
     if column > 0:
         return False
     
     parentNode = self.node(parent)
     
     if not data.hasFormat(self.MIMETYPE):
         if not data.hasUrls():
             return False
         
         from .BookmarkNode import BookmarkNode
         node = BookmarkNode(BookmarkNode.Bookmark, parentNode)
         node.url = bytes(data.urls()[0].toEncoded()).decode()
         
         if data.hasText():
             node.title = data.text()
         else:
             node.title = node.url
         
         self.__bookmarksManager.addBookmark(parentNode, node, row)
         return True
     
     ba = data.data(self.MIMETYPE)
     stream = QDataStream(ba, QIODevice.ReadOnly)
     if stream.atEnd():
         return False
     
     undoStack = self.__bookmarksManager.undoRedoStack()
     undoStack.beginMacro("Move Bookmarks")
     
     from .XbelReader import XbelReader
     while not stream.atEnd():
         encodedData = QByteArray()
         stream >> encodedData
         buffer = QBuffer(encodedData)
         buffer.open(QIODevice.ReadOnly)
         
         reader = XbelReader()
         rootNode = reader.read(buffer)
         for bookmarkNode in rootNode.children():
             rootNode.remove(bookmarkNode)
             row = max(0, row)
             self.__bookmarksManager.addBookmark(
                 parentNode, bookmarkNode, row)
             self.__endMacro = True
     
     return True
Beispiel #8
0
 def store_data(self, id, data):
     id = id.replace('/', '_')
     directory = ApplicationData.get('images')
     filename = os.path.join(directory, id + '.png')
     makedirs(directory)
     pixmap = QPixmap()
     if data is not None and pixmap.loadFromData(data):
         image_size = pixmap.size()
         if image_size.width() > self.max_size or image_size.height() > self.max_size:
             pixmap = pixmap.scaled(self.max_size, self.max_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
         if imghdr.what(None, data) != 'png' or pixmap.size() != image_size:
             buffer = QBuffer()
             pixmap.save(buffer, 'png')
             data = str(buffer.data())
         with open(filename, 'wb') as f:
             f.write(data)
         icon = QIcon(pixmap)
         icon.filename = filename
         icon.content = data
         icon.content_type = 'image/png'
     else:
         unlink(filename)
         icon = None
     self.iconmap[id] = icon
     return icon
Beispiel #9
0
 def dropEvent(self, event):
     mimeData = event.mimeData()
     if mimeData.hasUrls():
         paths = mimeData.urls()
         # pick just one image
         path = paths[0].toLocalFile()
         fileName = os.path.basename(path)
         with open(path, "rb") as imgFile:
             data = imgFile.read()
         ext = os.path.splitext(path)[1][1:]
         # TODO: make sure we cleanup properly when replacing an image with
         # another
         if ext.lower() != "png":
             # convert
             img = QImage(path)
             data = QByteArray()
             buffer = QBuffer(data)
             buffer.open(QIODevice.WriteOnly)
             img.save(buffer, 'PNG')
             # format
             data = bytearray(data)
             fileName = "%s.png" % os.path.splitext(fileName)[0]
         imageSet = self._glyph.font.images
         try:
             imageSet[fileName] = data
         except Exception as e:
             errorReports.showCriticalException(e)
             return
         image = self._glyph.instantiateImage()
         image.fileName = fileName
         event.setAccepted(True)
     else:
         super().dropEvent(event)
Beispiel #10
0
def image_and_format_from_data(data):
    ' Create an image object from the specified data which should be a bytestring and also return the format of the image '
    ba = QByteArray(data)
    buf = QBuffer(ba)
    buf.open(QBuffer.ReadOnly)
    r = QImageReader(buf)
    fmt = bytes(r.format()).decode('utf-8')
    return r.read(), fmt
Beispiel #11
0
    def take_screenshot(self):
        byte_array = QByteArray()
        buffer = QBuffer(byte_array)
        buffer.open(QIODevice.WriteOnly)

        image = self.__screen.grabWindow(QApplication.desktop().winId())
        image.save(buffer, "PNG")

        return str(byte_array.toBase64())[1:]
    def requestStarted(self, job):
        """Handle a request for a qute: scheme.

        This method must be reimplemented by all custom URL scheme handlers.
        The request is asynchronous and does not need to be handled right away.

        Args:
            job: QWebEngineUrlRequestJob
        """
        url = job.requestUrl()

        if url.scheme() in ['chrome-error', 'chrome-extension']:
            # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-63378
            job.fail(QWebEngineUrlRequestJob.UrlInvalid)
            return

        if not self._check_initiator(job):
            return

        if job.requestMethod() != b'GET':
            job.fail(QWebEngineUrlRequestJob.RequestDenied)
            return

        assert url.scheme() == 'qute'

        log.misc.debug("Got request for {}".format(url.toDisplayString()))
        try:
            mimetype, data = qutescheme.data_for_url(url)
        except qutescheme.Error as e:
            errors = {
                qutescheme.NotFoundError:
                    QWebEngineUrlRequestJob.UrlNotFound,
                qutescheme.UrlInvalidError:
                    QWebEngineUrlRequestJob.UrlInvalid,
                qutescheme.RequestDeniedError:
                    QWebEngineUrlRequestJob.RequestDenied,
                qutescheme.SchemeOSError:
                    QWebEngineUrlRequestJob.UrlNotFound,
                qutescheme.Error:
                    QWebEngineUrlRequestJob.RequestFailed,
            }
            exctype = type(e)
            log.misc.error("{} while handling qute://* URL".format(
                exctype.__name__))
            job.fail(errors[exctype])
        except qutescheme.Redirect as e:
            qtutils.ensure_valid(e.url)
            job.redirect(e.url)
        else:
            log.misc.debug("Returning {} data".format(mimetype))

            # We can't just use the QBuffer constructor taking a QByteArray,
            # because that somehow segfaults...
            # https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html
            buf = QBuffer(parent=self)
            buf.open(QIODevice.WriteOnly)
            buf.write(data)
            buf.seek(0)
            buf.close()
            job.reply(mimetype.encode('ascii'), buf)
Beispiel #13
0
    def sendMessage(self):
        textbuf = QBuffer()
        textbuf.open(QBuffer.ReadWrite)
        messageText = QDataStream(textbuf)
        messageText << self.ui.messageBox.text
        size = textbuf.size()

        if not self.shareMemory.create(size):
            return

        size = min(self.shareMemory.size(), size)
        self.sharedMemory.lock()
Beispiel #14
0
    def fillImageFaster(self, begin, paint, current, image):

        buffer = QBuffer()
        buffer.open(QBuffer.ReadWrite)

        image.save(buffer, "PNG")

        pil_im = Image.open(io.BytesIO(buffer.data()))
        ImageDraw.floodfill(pil_im, begin, (paint.red(), paint.green(), paint.blue()))

        self.image().image = QtGui.QImage(pil_im.convert("RGB").tobytes("raw", "RGB"), pil_im.size[0], pil_im.size[1], QtGui.QImage.Format_RGB888)
        self.update()
Beispiel #15
0
    def loadFromFile(self):
        """ This slot function is called when the "Load Image From File..."
        button is pressed on the firs Dialog process.  First, it tests whether
        the process is already connected to a shared memory segment and, if so,
        detaches from that segment.  This ensures that we always start the
        example from the beginning if we run it multiple times with the same
        two Dialog processes.  After detaching from an existing shared memory
        segment, the user is prompted to select an image file.  The selected
        file is loaded into a QImage.  The QImage is displayed in the Dialog
        and streamed into a QBuffer with a QDataStream.  Next, it gets a new
        shared memory segment from the system big enough to hold the image data
        in the QBuffer, and it locks the segment to prevent the second Dialog
        process from accessing it.  Then it copies the image from the QBuffer
        into the shared memory segment.  Finally, it unlocks the shared memory
        segment so the second Dialog process can access it.  After self
        function runs, the user is expected to press the "Load Image from
        Shared Memory" button on the second Dialog process.
        """

        if self.sharedMemory.isAttached():
            self.detach()

        self.ui.label.setText("Select an image file")
        fileName, _ = QFileDialog.getOpenFileName(self, None, None,
                "Images (*.png *.xpm *.jpg)")
        image = QImage()
        if not image.load(fileName):
            self.ui.label.setText(
                    "Selected file is not an image, please select another.")
            return

        self.ui.label.setPixmap(QPixmap.fromImage(image))

        # Load into shared memory.
        buf = QBuffer()
        buf.open(QBuffer.ReadWrite)
        out = QDataStream(buf)
        out << image
        size = buf.size()

        if not self.sharedMemory.create(size):
            self.ui.label.setText("Unable to create shared memory segment.")
            return

        size = min(self.sharedMemory.size(), size)
        self.sharedMemory.lock()

        # Copy image data from buf into shared memory area.
        self.sharedMemory.data()[:] = buf.data().data()
        self.sharedMemory.unlock()
Beispiel #16
0
def encode_jpeg(file_path, quality=80):
    from calibre.utils.speedups import ReadOnlyFileBuffer
    quality = max(0, min(100, int(quality)))
    exe = get_exe_path('cjpeg')
    cmd = [exe] + '-optimize -progressive -maxmemory 100M -quality'.split() + [str(quality)]
    img = QImage()
    if not img.load(file_path):
        raise ValueError('%s is not a valid image file' % file_path)
    ba = QByteArray()
    buf = QBuffer(ba)
    buf.open(QBuffer.WriteOnly)
    if not img.save(buf, 'PPM'):
        raise ValueError('Failed to export image to PPM')
    return run_optimizer(file_path, cmd, as_filter=True, input_data=ReadOnlyFileBuffer(ba.data()))
Beispiel #17
0
 def setImage(self, image):
     """
     Public method to set the image of the engine.
     
     @param image image to be set (QImage)
     """
     if not self._imageUrl:
         imageBuffer = QBuffer()
         imageBuffer.open(QIODevice.ReadWrite)
         if image.save(imageBuffer, "PNG"):
             self._imageUrl = "data:image/png;base64,{0}".format(
                 bytes(imageBuffer.buffer().toBase64()).decode())
     
     self.__image = QImage(image)
     self.imageChanged.emit()
Beispiel #18
0
    def createData(self, mimeType):
        if mimeType != 'image/png':
            return

        image = QImage(self.imageLabel.size(), QImage.Format_RGB32)
        painter = QPainter()
        painter.begin(image)
        self.imageLabel.renderer().render(painter)
        painter.end()

        data = QByteArray()
        buffer = QBuffer(data)
        buffer.open(QIODevice.WriteOnly)
        image.save(buffer, 'PNG')
        buffer.close()
        self.mimeData.setData('image/png', data)
 def capture(self, fullScreen = False, filename = ''):
     if fullScreen:
         image = QApplication.primaryScreen().grabWindow(0)
     else:
         image = QImage(self.webView.mainFrame.contentsSize(), QImage.Format_ARGB32)
         painter = QPainter(image)
         self.webView.mainFrame.render(painter)
         painter.end()
     if filename:
         return image.save(filename)
     else:
         data = QByteArray()
         buffer = QBuffer(data)
         buffer.open(QBuffer.WriteOnly)
         image.save(buffer, 'PNG')
         return bytes(data.toBase64()).decode()
Beispiel #20
0
 def __getitem__(key):
    if key not in IconCache.icons:
       if not key.endswith('.svg') and not key.endswith('.svgz'):
          image = QImage(key).scaled(24, 24)
       else:
          svg = QSvgRenderer(key)
          image = QImage(24, 24, QImage.Format_ARGB32)
          image.fill(0)
          painter = QPainter(image)
          svg.render(painter)
          painter.end()
       bytes = QByteArray()
       buff = QBuffer(bytes)
       buff.open(QIODevice.WriteOnly)
       image.save(buff, 'png')
       IconCache.icons[key] = bytes
    return QIcon(QPixmap.fromImage(QImage.fromData(IconCache.icons[key])))
    def _setNewImage(self, image):
        maxWidth = 16
        maxHeight = 16
        if image.width() > maxWidth or image.height() > maxHeight:
            scaledImage = image.scaled(maxWidth, maxHeight,
                    Qt.KeepAspectRatio, Qt.SmoothTransformation)
        else:
            scaledImage = image

        ba = QByteArray()
        buffer = QBuffer(ba)
        buffer.open(QIODevice.WriteOnly)
        scaledImage.save(buffer, 'png')

        model = self.model()
        index = model.index(self.selectedIndex().row(), model.sourceModel().fieldIndex('icon'))
        model.setData(index, ba)
 def sendDeleteRequest(self, endpoint, data={}, params={}, headers={}):
     buff = QBuffer()
     buff.open(QBuffer.ReadWrite)
     d = json.dumps(data).encode('utf-8')
     buff.write(d)
     buff.seek(0)
     headers.update({"Content-Type":"application/json"})
     content = self.sendRequest( endpoint, params,
         'delete',
         buff,
         headers=headers
     )
     buff.close()
     return content
Beispiel #23
0
 def __cssLinkClass(self, icon, size=32):
     """
     Private method to generate a link class with an icon.
     
     @param icon icon to be included (QIcon)
     @param size size of the icon to be generated (integer)
     @return CSS class string (string)
     """
     cssString = \
         """a.{{0}} {{{{\n"""\
         """  padding-left: {0}px;\n"""\
         """  background: transparent url(data:image/png;base64,{1})"""\
         """ no-repeat center left;\n"""\
         """  font-weight: bold;\n"""\
         """}}}}\n"""
     pixmap = icon.pixmap(size, size)
     imageBuffer = QBuffer()
     imageBuffer.open(QIODevice.ReadWrite)
     if not pixmap.save(imageBuffer, "PNG"):
         # write a blank pixmap on error
         pixmap = QPixmap(size, size)
         pixmap.fill(Qt.transparent)
         imageBuffer.buffer().clear()
         pixmap.save(imageBuffer, "PNG")
     return cssString.format(
         size + 4,
         str(imageBuffer.buffer().toBase64(), encoding="ascii"))
Beispiel #24
0
 def open(self, _fname, mode):
     """Open an in-memory PyQIODevice instead of a real file."""
     modes = {
         'wb': QIODevice.WriteOnly | QIODevice.Truncate,
         'w': QIODevice.WriteOnly | QIODevice.Text | QIODevice.Truncate,
         'rb': QIODevice.ReadOnly,
         'r': QIODevice.ReadOnly | QIODevice.Text,
     }
     try:
         qt_mode = modes[mode]
     except KeyError:
         raise ValueError("Invalid mode {}!".format(mode))
     f = QBuffer(self._data)
     f.open(qt_mode)
     qiodev = qtutils.PyQIODevice(f)
     # Make sure tests using name/mode don't blow up.
     qiodev.name = test_file.TESTFN
     qiodev.mode = mode
     # Create empty TESTFN file because the Python tests try to unlink
     # it.after the test.
     open(test_file.TESTFN, 'w', encoding='utf-8').close()
     return qiodev
Beispiel #25
0
    def __init__(self, job, engine, parent=None):
        """
        Constructor

        :param job: reference to the URL request
        :type job: QWebEngineUrlRequestJob
        :param engine: reference to the help engine
        :type engine: QHelpEngine
        :param parent: reference to the parent object
        :type parent: QObject
        """
        super(HelpSchemeReply, self).__init__(parent)

        url = job.requestUrl()
        strUrl = url.toString()

        self.__buffer = QBuffer()

        # For some reason the url to load maybe wrong (passed from web engine)
        # though the css file and the references inside should work that way.
        # One possible problem might be that the css is loaded at the same
        # level as the html, thus a path inside the css like
        # (../images/foo.png) might cd out of the virtual folder
        if not engine.findFile(url).isValid():
            if strUrl.startswith(QtHelp_DOCROOT):
                newUrl = job.requestUrl()
                if not newUrl.path().startswith("/qdoc/"):
                    newUrl.setPath("/qdoc" + newUrl.path())
                    url = newUrl
                    strUrl = url.toString()

        self.__mimeType = mimetypes.guess_type(strUrl)[0]
        if self.__mimeType is None:
            # do our own (limited) guessing
            self.__mimeType = self.__mimeFromUrl(url)

        if engine.findFile(url).isValid():
            data = engine.fileData(url)
        else:
            data = QByteArray(self.tr(
                """<html>"""
                """<head><title>Error 404...</title></head>"""
                """<body><div align="center"><br><br>"""
                """<h1>The page could not be found</h1><br>"""
                """<h3>'{0}'</h3></div></body>"""
                """</html>""").format(strUrl)
                              .encode("utf-8"))

        self.__buffer.setData(data)
        self.__buffer.open(QIODevice.ReadOnly)
        self.open(QIODevice.ReadOnly)
    def requestStarted(self, job):
        """Handle a request for a qute: scheme.

        This method must be reimplemented by all custom URL scheme handlers.
        The request is asynchronous and does not need to be handled right away.

        Args:
            job: QWebEngineUrlRequestJob
        """
        url = job.requestUrl()
        assert job.requestMethod() == b'GET'
        assert url.scheme() == 'qute'
        log.misc.debug("Got request for {}".format(url.toDisplayString()))
        try:
            mimetype, data = qutescheme.data_for_url(url)
        except qutescheme.NoHandlerFound:
            log.misc.debug("No handler found for {}".format(
                url.toDisplayString()))
            job.fail(QWebEngineUrlRequestJob.UrlNotFound)
        except qutescheme.QuteSchemeOSError:
            # FIXME:qtwebengine how do we show a better error here?
            log.misc.exception("OSError while handling qute://* URL")
            job.fail(QWebEngineUrlRequestJob.UrlNotFound)
        except qutescheme.QuteSchemeError:
            # FIXME:qtwebengine how do we show a better error here?
            log.misc.exception("Error while handling qute://* URL")
            job.fail(QWebEngineUrlRequestJob.RequestFailed)
        except qutescheme.Redirect as e:
            qtutils.ensure_valid(e.url)
            job.redirect(e.url)
        else:
            log.misc.debug("Returning {} data".format(mimetype))

            # We can't just use the QBuffer constructor taking a QByteArray,
            # because that somehow segfaults...
            # https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html
            buf = QBuffer(parent=self)
            buf.open(QIODevice.WriteOnly)
            buf.write(data)
            buf.seek(0)
            buf.close()
            job.reply(mimetype.encode('ascii'), buf)
Beispiel #27
0
def fromqimage(im):
    buffer = QBuffer()
    buffer.open(QIODevice.ReadWrite)
    im.save(buffer, 'ppm')

    b = BytesIO()
    try:
        b.write(buffer.data())
    except TypeError:
        # workaround for Python 2
        b.write(str(buffer.data()))
    buffer.close()
    b.seek(0)

    return PIL.Image.open(b)
    def perform_delete(self, endpoint, data, url):
        """
        Perform an HTTP DELETE request.

        :param endpoint: the name of the Tribler endpoint.
        :param data: the data/body to send with the request.
        :param url: the url to send the request to.
        """
        buf = QBuffer()
        buf.setData(data)
        buf.open(QIODevice.ReadOnly)
        delete_request = QNetworkRequest(QUrl(url))
        reply = self.sendCustomRequest(delete_request, "DELETE", buf)
        buf.setParent(reply)
        return reply
Beispiel #29
0
def scale(image, width, height):
    edited = QImage.fromData(image.data, format_for(image.mime))
    if edited.isNull():
        return image

    scaled = edited.scaled(width, height, Qt.KeepAspectRatio, Qt.SmoothTransformation)

    buffer = QBuffer()
    buffer.open(QIODevice.WriteOnly)
    scaled.save(buffer, format_for(image.mime))
    buffer.close()
    return Image(mime=image.mime, data=buffer.data(), desc=image.desc, type_=image.type)
    def _resizeImage(self, virtual_path: str, width: int,
                     height: int) -> IO[bytes]:
        input = self.getStream(virtual_path)
        try:
            from PyQt5.QtGui import QImage
            from PyQt5.QtCore import Qt, QBuffer

            image = QImage()
            image.loadFromData(input.read())
            image = image.scaled(width, height, Qt.IgnoreAspectRatio,
                                 Qt.SmoothTransformation)
            output_buffer = QBuffer()
            output_buffer.open(QBuffer.ReadWrite)
            image.save(output_buffer, "PNG")
            output_buffer.seek(
                0)  # Reset that buffer so that the next guy can request it.
            return BytesIO(output_buffer.readAll())
        except ImportError:
            # TODO: Try other image loaders.
            raise  # Raise import error again if we find no other image loaders.
    def init_ui(self):
        self.setMinimumWidth(320)
        self.setMinimumHeight(240)
        lb = QLabel()
        te = QTextEdit()
        layout = QBoxLayout(QBoxLayout.LeftToRight)
        layout.addWidget(lb)
        layout.addWidget(te)
        self.setLayout(layout)

        # 사용할 그림 설정
        pixmap = QPixmap("apple.jpg")
        pixmap = pixmap.scaledToHeight(100)  # 사이즈가 조정
        lb.setPixmap(pixmap)

        # PNG 포맷 및 Base64로 변환
        image: QImage = pixmap.toImage()
        data = QByteArray()
        buffer = QBuffer(data)
        image.save(buffer, 'PNG')

        te.setText(str(data.toBase64()))
def fromqimage(im):
    """
    :param im: A PIL Image object, or a file name
    (given either as Python string or a PyQt string object)
    """
    buffer = QBuffer()
    buffer.open(QIODevice.ReadWrite)
    # preserve alpha channel with png
    # otherwise ppm is more friendly with Image.open
    if im.hasAlphaChannel():
        im.save(buffer, "png")
    else:
        im.save(buffer, "ppm")

    b = BytesIO()
    b.write(buffer.data())
    buffer.close()
    b.seek(0)

    return Image.open(b)
 def get_piclist_data_to_dict(self):
     for i in range(self.count()):
         try:
             item = self.item(i)
             if item.checkState() != Qt.Checked:
                 continue
             icon = item.icon()
             if icon:
                 pixmap = icon.pixmap(icon.availableSizes()[0])
                 array = QByteArray()
                 buffer = QBuffer(array)
                 buffer.open(QIODevice.WriteOnly)
                 pixmap.save(buffer, 'JPG')
                 buffer.close()
                 yield array.data()
         except Exception:
             pass
    def Guardar(self):
        # Obtener el nombre de usuario y la foto
        nombre = " ".join(self.lineEditNombre.text().split()).title()
        foto = self.labelImagen.pixmap()

        if foto:
            # Convertir la foto al tipo de dato adecuado
            bArray = QByteArray()
            bufer = QBuffer(bArray)
            bufer.open(QIODevice.WriteOnly)
            bufer.close()
            foto.save(bufer, "PNG")
        else:
            bArray = ""

        if nombre and bArray:
            # Establecer conexión con la base de datos
            conexion = connect("DB_USUARIOS.db")
            cursor = conexion.cursor()

            # Crear tabla, si no existe
            cursor.execute(
                "CREATE TABLE IF NOT EXISTS Usuarios (NOMBRE TEXT, FOTO BLOB)")
            conexion.commit()

            # Verificar que el usuario no exista
            if cursor.execute("SELECT * FROM Usuarios WHERE NOMBRE = ?",
                              (nombre, )).fetchone():
                print("El usaurio {} ya existe.".format(nombre))
            else:
                # Guardar en la base de datos, el nombre de usuario y la foto
                cursor.execute("INSERT INTO Usuarios VALUES (?,?)",
                               (nombre, bArray))
                conexion.commit()

                self.labelImagen.clear()
                self.lineEditNombre.clear()

                print("Usuario guardado con éxito.")

            # Cerrar la conexión con la base de datos
            conexion.close()

            self.lineEditNombre.setFocus()
        else:
            self.lineEditNombre.setFocus()
Beispiel #35
0
def fromqimage(im):
    """
    :param im: A PIL Image object, or a file name
    (given either as Python string or a PyQt string object)
    """
    buffer = QBuffer()
    buffer.open(QIODevice.ReadWrite)
    # preserve alha channel with png
    # otherwise ppm is more friendly with Image.open
    if im.hasAlphaChannel():
        im.save(buffer, 'png')
    else:
        im.save(buffer, 'ppm')

    b = BytesIO()
    try:
        b.write(buffer.data())
    except TypeError:
        # workaround for Python 2
        b.write(str(buffer.data()))
    buffer.close()
    b.seek(0)

    return Image.open(b)
Beispiel #36
0
    def ReadText(self):
        # -------------------------------------------------------------- #
        # Alex Walker have a look below! ------------------------------- #

        buffer = QBuffer()
        buffer.open(QIODevice.ReadWrite)
        self.canvas.image.save(buffer, "PNG")
        data = BytesIO(buffer.data())
        buffer.close()
        img = Image.open(data)  # PIL image format

        # -------------------------------------------------------------- #

        thresh = 200
        fn = lambda x: 255 if x > thresh else 0
        mod = img.convert('L').point(fn, mode='1')

        text = pytesseract.image_to_string(mod, config='--psm 10')
        text = text.replace("~¦", "")
        self.pages[self.display.currentIndex()].insertPlainText(text.strip())
        self.canvas.clearImage()
Beispiel #37
0
    def generate_gif(self):
        img: Image
        imgs: List[Image]

        # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
        select_frames_labels = self.layout_children(self.select_frames_layout)
        if not select_frames_labels:
            self.adjust_corgo()
            return
        pixmaps = [
            i.original_pixmap for i in select_frames_labels if i.highlighted
        ]
        height = int(self.height.text())
        img, *imgs = [
            qpixmap_to_pil(i.scaledToHeight(height)) for i in pixmaps
        ]

        delay = int(self.delay.text())

        bytesio = io.BytesIO()
        img.save(fp=bytesio,
                 format='GIF',
                 append_images=imgs,
                 save_all=True,
                 duration=delay,
                 loop=0)
        self.gif_qbytearray = QByteArray(bytesio.getvalue())
        bytesio.close()
        self.gif_qbuffer = QBuffer(self.gif_qbytearray)

        gif = QMovie()
        gif.setDevice(self.gif_qbuffer)
        gif.setCacheMode(QMovie.CacheAll)
        print(f'Movie isValid() {gif.isValid()}')

        self.gif_view.setMovie(gif)
        gif.start()
Beispiel #38
0
    async def handleImage(self, requestId, img):
        scaledImage = img.scaled(self.ui.viewfinder.size(), Qt.KeepAspectRatio,
                                 Qt.SmoothTransformation)

        self.ui.lastImagePreviewLabel.setPixmap(QPixmap.fromImage(scaledImage))
        self.displayCapturedImage()

        imgFormat = self.ui.captureImageFormat.currentText()

        array = QByteArray()
        buffer = QBuffer(array)
        buffer.open(QIODevice.WriteOnly)
        img.save(buffer, imgFormat)
        buffer.close()

        await self.importImageBuffer(buffer, imgFormat.lower())

        QTimer.singleShot(3000, self.displayViewfinder)
Beispiel #39
0
	def imageToSql(self, pathimage, idcd, minisize):
		"""Write image and thunbnail to database."""
		# just file
		#file = QFile(pathimage)
		#file.open(QIODevice.ReadOnly)
		#inByteArray = QByteArray(file.readAll())
		
		# image big
		#print(path.getsize(pathimage))
		inPixmap = QPixmap(pathimage)
		inByteArray = QByteArray()
		inBuffer = QBuffer(inByteArray)
		if not inBuffer.open(QIODevice.WriteOnly):
			return False
		inPixmap.save(inBuffer,"JPG");
		
		# image mini # Qt.FastTransformation
		inPixmap = inPixmap.scaled(minisize, minisize, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) 
		inByteArraymini = QByteArray()
		inBuffer = QBuffer(inByteArraymini)
		inBuffer.open(QIODevice.WriteOnly);
		inPixmap.save(inBuffer,"JPG");
		
		# mssql
		# https://stackoverflow.com/questions/108403/solutions-for-insert-or-update-on-sql-server
		# UPDATE data or INSERT : https://en.wikipedia.org/wiki/Merge_(SQL)
		query = QSqlQuery()
		request = getrequest('insertcover')
		query.prepare(request)
		query.bindValue(0, idcd)
		query.bindValue(1, pathimage)
		query.bindValue(2, inByteArray)
		query.bindValue(3, inByteArraymini)
		if not query.exec_():
			qDebug(10*' '+":index "+query.lastError().text())
			return False
		return True
    def extract(self, page: Poppler.Page):
        from tesserocr import PyTessBaseAPI  # NOQA Stupid assert on LC_* == 'C'

        ocr = PyTessBaseAPI(lang=settings.CAMPUSONLINE_BULLETIN_OCR_LANGUAGE)
        text = page.text(QRectF()).strip()
        if len(text) > settings.CAMPUSONLINE_BULLETIN_OCR_THRESHOLD:
            self.clean = True
            self.text = text
            return
        dpi = settings.CAMPUSONLINE_BULLETIN_OCR_DPI
        buf = QBuffer()
        buf.open(QIODevice.ReadWrite)
        page.renderToImage(dpi, dpi).save(buf, "PNG")
        bio = BytesIO()
        bio.write(buf.data())
        buf.close()
        bio.seek(0)
        img = Image.open(bio)
        ocr.SetImage(img)
        scanned = ocr.GetUTF8Text().strip()
        img.close()
        bio.close()
        self.clean = False
        self.text = scanned
Beispiel #41
0
def screenshot():
    app = QtWidgets.QApplication(sys.argv)

    image = QtWidgets.QApplication.screens()[0].grabWindow(
        QtWidgets.QApplication.desktop().winId(), 0, 0,
        QtWidgets.QApplication.desktop().screenGeometry().width(),
        QtWidgets.QApplication.desktop().screenGeometry().height())

    size = QSize(SRC_W, SRC_H)

    image = image.scaled(size)

    buffer = QBuffer()
    buffer.open(QIODevice.WriteOnly)
    image.save(buffer, "PNG")

    strio = BytesIO()
    strio.write(buffer.data())
    buffer.close()
    strio.seek(0)
    img = imread(strio)

    test = prepare_image(img)
    return test
Beispiel #42
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()
Beispiel #43
0
 def to_jpeg(self, quality=None):
     if quality is None:
         quality = defaults.JPEG_QUALITY
     buf = QBuffer()
     self.img.save(buf, 'jpeg', quality)
     return bytes(buf.data())
Beispiel #44
0
 def to_png(self, complevel=defaults.PNG_COMPRESSION_LEVEL):
     quality = 90 - (complevel * 10)
     buf = QBuffer()
     self.img.save(buf, 'png', quality)
     return bytes(buf.data())
Beispiel #45
0
class ContourRoundRectangle():

    #
    # define your own images to describe your GCode-Generator
    def __init__(self, parent):
        path = os.getcwd()

        self.__imageNames = [
            # left down
            path + "/img/contour/round-rectangle-pic1_1.jpg",
            path + "/img/contour/round-rectangle-pic1_2.jpg",
        ]

        self.parent = parent
        self.window = parent.window
        self.centerPos = 0

        self.window.rbCPRR_1.clicked.connect(
            lambda clicked: self.onCenterPosChange(0))
        self.window.rbCPRR_2.clicked.connect(
            lambda clicked: self.onCenterPosChange(1))

        self.window.rbTrcRRect.clicked.connect(
            lambda clicked: self.onToolMoveChanged("on"))
        self.window.rbTrclRRect.clicked.connect(
            lambda clicked: self.onToolMoveChanged("left"))
        self.window.rbTrcrrRect.clicked.connect(
            lambda clicked: self.onToolMoveChanged("right"))

        self.window.edgeRadius.editingFinished.connect(
            self.onEdgeRadiusChanged)

        self.arcPix = False
        self.buffer = QBuffer()
        self.pixmap = QPixmap()
        self.painter = QPainter()

        for i in range(1, 3):
            obj = "rbCPRR_" + str(i)
            attr = getattr(self.window, obj)
            if attr.isChecked():
                attr.clicked.emit()

        self.updateMillTool()
        self.drawRoundedRect(1.0)

    def updateMillTool(self):

        if self.window.rbTrcRRect.isChecked():
            self.window.rbTrcRRect.clicked.emit()
        elif self.window.rbTrclRRect.isChecked():
            self.window.rbTrclRRect.clicked.emit()
        elif self.window.rbTrcrrRect.isChecked():
            self.window.rbTrcrrRect.clicked.emit()

    def updatePosForm(self, boolean):
        self.window.posRRX.setEnabled(boolean)
        self.window.posRRY.setEnabled(boolean)
        self.window.labelRRX.setEnabled(boolean)
        self.window.labelRRY.setEnabled(boolean)

    def onCenterPosChange(self, pos):
        if self.pixmap.load(self.__imageNames[pos]):
            self.window.imageRR.setPixmap(self.pixmap)
            self.drawCenterPos(pos)
        else:
            print("Image Load Error ", self.__imageNames[pos])

    def onToolMoveChanged(self, pos):
        self.arcPix = False
        if pos == "on":
            self.drawMiller(40)
        elif pos == "right":
            self.drawMiller(20)
        elif pos == "left":
            self.drawMiller(60)

    def onEdgeRadiusChanged(self):
        value = self.window.edgeRadius.text()
        self.drawRoundedRect(float(value))

    def drawRoundedRect(self, r):
        pen = QtGui.QPen()
        pen.setWidth(2)
        pen.setColor(QtGui.QColor('black'))
        pix = QPixmap()
        if self.arcPix:
            pix.loadFromData(self.buffer.data())
        else:
            pix = self.window.imageRR.pixmap()
            self.buffer.open(QBuffer.ReadWrite)
            pix.save(self.buffer, "PNG")
            self.arcPix = True
        self.painter.begin(pix)
        self.painter.setPen(pen)
        self.painter.drawRoundedRect(40, 78, 220, 150, r, r)

        self.painter.end()
        self.window.imageRR.setPixmap(pix)

    # self.window.imageRR.update()

    def drawCenterPos(self, pos):
        pen = QtGui.QPen()
        pen.setWidth(3)
        pen.setColor(QtGui.QColor('red'))
        pix = QPixmap()
        pix = self.pixmap
        self.painter.begin(pix)

        self.painter.setPen(pen)

        if pos == 0:
            xh = 40
            yh = pix.height() - 40
            self.painter.drawLine(xh - 10, yh, xh + 10, yh)
            self.painter.drawLine(xh, yh - 10, xh, yh + 10)
            self.updatePosForm(True)

        if pos == 1:
            xh = pix.width() / 2
            yh = pix.height() / 2
            self.painter.drawLine(xh - 10, yh, xh + 10, yh)
            self.painter.drawLine(xh, yh - 10, xh, yh + 10)
            self.updatePosForm(False)

        self.painter.end()

        self.updateMillTool()

    def drawMiller(self, pos):
        pen = QtGui.QPen()
        pen.setWidth(30)
        pen.setColor(QtGui.QColor('blue'))
        self.window.imageRR.setPixmap(self.pixmap)
        pix = self.window.imageRR.pixmap()
        self.painter.begin(pix)
        self.painter.setPen(pen)
        self.painter.drawEllipse(pix.width() - pos, pix.height() / 2, 4, 4)
        self.painter.end()
        self.window.image.update()
        self.window.edgeRadius.editingFinished.emit()

    #-------------------------------------------------------------
    # here you generate your GCode.
    # some of this code should be used every time.
    # insert your code bettween marked rows
    #-------------------------------------------------------------
    def generateGCode(self, parent):
        '''
        generate GCode for a rounded rectangle.
        This class is copied from pocketRoundRectangle. Some unnessesary
        code are removed. Some parts are new (cutter compensation)
        '''
        print("ContourRoundRect")
        cPoint = (float(self.window.posRRX.text()),
                  float(self.window.posRRY.text()))
        sizeAB = (float(self.window.heightRA.text()),
                  float(self.window.heightRB.text()))
        radius = float(self.window.edgeRadius.text())
        toolDia = float(self.window.toolDiameter.text())

        zPos = {
            "safetyZ": float(self.window.zSafe.text()),
            "startZ": float(self.window.startZ.text())
        }

        depth = (float(self.window.depthRRTotal.text()),
                 float(self.window.depthRRStep.text()))

        dir = parent.commonGcode.getDir()

        feeds = {
            "XYG0": float(self.window.speedXY.text()),
            "XYGn": float(self.window.speedG2G3.text()),
            "ZG0": float(self.window.speedZ.text()),
            "ZGn": float(self.window.speedZg1.text())
        }
        gc = ""
        gc += self.window.preamble.text()
        # set Unit
        gc += parent.commonGcode.getUnit() + CR
        # set Z axis
        gc += CR + "(set Z saftey position)" + CR
        gc += "G00 Z{0:08.3f} F{1:05.1f} {2}".format(zPos["safetyZ"],
                                                     feeds["ZG0"], CR)

        #
        # even which center point user choosed, we start on
        # center point object - left down (5)

        if self.centerPos == 5:
            cPoint = (0.0 - (sizeAB[1] / 2.0), 0.0 - (sizeAB[0] / 2.0))

        # set start postion X/Y
        gc += CR + "(set center position)" + CR
        gc += "G00 X{0:08.3f} Y{1:08.3f} F{2:05.1f} {3}".format(
            cPoint[0], cPoint[1], feeds["XYG0"], CR)
        #
        # generate as many shape steps are needed until depthtotal is reached
        # cut an Arc
        step = depth[1]
        #        depth = float(self.__depthtotal.get())
        z = step
        loop = ""
        gc += CR + "(------- start shape -------------)" + CR

        # start with shape
        gc += CR + "(move Z-axis to start postion near surface)" + CR
        gc += "G00 Z{0:08.3f} F{1:05.1f} {2}".format(zPos["startZ"],
                                                     feeds["ZG0"], CR)
        spaces = "".ljust(2)
        #----------------------------------------------------------------------
        # This loop asume, that you try to mill into your object.
        # if not needed for your shape, remove this part and rewrite
        #----------------------------------------------------------------------
        #

        pocketMillTracks = []
        x = 1
        t = self.__createPocketTracks(
            cPoint,
            sizeAB,
            radius,
            feeds,
            0.0  # no offset, milling only one time !
        )

        pocketMillTracks.append(t)
        #gc += self.getGCodeCutterComp(self.__cuttercompensation.get(), toolDia)
        gc += parent.commonGcode.getGCodeCutterComp(
            parent.commonGcode.getCompensation(), toolDia)

        #
        # it's time to generate the real gCode
        #
        # Every round we mill all tracks in the same detph
        # than we increase depth as long as we reached total depthStep

        gc += CR + "(-- START DEPTH Loop --)" + CR
        z = depth[1]

        while (abs(z) < abs(depth[0])):
            # set next Z depth
            print("Z: ", abs(z), " MaxD: ", abs(depth[0]))
            if ((abs(depth[0]) - abs(z)) < abs(depth[1])):
                # this happens, if a small amount is the rest
                z -= (abs(depth[0]) - abs(z))
                print("rest Z: ", z)
            else:
                z -= abs(depth[1])
                print("new Z: ", z)

            loop += CR
            gc += spaces + "(-- START Track Loop  --)" + CR

            for t in pocketMillTracks:
                # every track contain a fixed number of separate gCode
                # commands
                print(t)
                spaces2 = spaces.ljust(2)
                # set new depth
                gc += CR + spaces2 + "(-- next depth z {0:08.3f} --){1}".format(
                    z, CR)
                gc += spaces2 + "G01 Z{0:08.3f} {1}".format(z, CR)
                for cmd in list(t):
                    #
                    # combine all parameter to one command
                    gc += spaces2
                    #  0  1  2  3  4
                    # GC, X, Y, I, J
                    print(cmd)
                    for p in range(len(cmd)):
                        if p == 0:
                            gc += cmd[p]
                        if p == 1:
                            f = " F{0:05.1f}".format(float(cmd[p]))
                        if p == 2:
                            gc += " X{0:08.3f}".format(float(cmd[p]))
                        if p == 3:
                            gc += " Y{0:08.3f}".format(float(cmd[p]))
                        if p == 4:
                            gc += " I{0:08.3f}".format(float(cmd[p]))
                        if p == 5:
                            gc += " J{0:08.3f}".format(float(cmd[p]))

                    gc += f + CR

            gc += spaces + "(-- END Track Loop  --)" + CR
            pass

        gc += "(-- END DEPTH loop --)" + CR
        gc += parent.commonGcode.getGCode_Homeing(cPoint[0], cPoint[1],
                                                  zPos["safetyZ"],
                                                  feeds["XYG0"])
        gc += self.window.postGcode.text()
        gc += CR
        return gc

    def __createPocketTracks(self, cPoint, sizeAB, r, feeds, offset=0.0):
        '''
        This method create for a track all needed GCode parameters and save
        them in a list. This list is used (afterwards) to create the real
        GCode commands

        This method is called in a loop with a new offset. The offset describes
        next millings position
        '''
        # h = h1 + 2*r
        # w = w1 + 2*r
        w0 = sizeAB[1]
        w1 = sizeAB[1] - (2 * r)  # horizontal distance between arcs
        h0 = sizeAB[0]
        h1 = sizeAB[0] - (2 * r)  # vertical distance betwween arcs

        x = cPoint[0]
        y = cPoint[1]
        # sequence to mill a rounded rectangle
        seq = []
        #start
        seq.append(("G01", feeds["XYGn"], x, y - offset))
        # arc1
        # G02, F X Y I J
        if r > 0:
            seq.append(
                ("G02", feeds["XYGn"], x - r - offset, y + r, 0.0, r + offset))
            # vertical to arc2

        seq.append(("G01", feeds["XYGn"], x - r - offset, y + r + h1))
        # arc2
        # G02, F X Y I J
        if r > 0:
            seq.append(
                ("G02", feeds["XYGn"], x, y + h0 + offset, r + offset, 0.0))
            # horizontal to arc 3
        seq.append(("G01", feeds["XYGn"], x + w1, y + h0 + offset))
        # arc 3
        # G02, F X Y I J
        if r > 0:
            seq.append(("G02", feeds["XYGn"], x + w1 + r + offset, y + r + h1,
                        0.0, -r - offset))
            # vertical to arc 4
        seq.append(("G01", feeds["XYGn"], x + w1 + r + offset, y + r))
        # arc 4
        # G02, G02, F X Y I J
        if r > 0:
            seq.append(
                ("G02", feeds["XYGn"], x + w1, y - offset, -r - offset, 0.0))
            # go back to start position
        seq.append(("G01", feeds["XYGn"], x, y - offset))

        #print "{1}---- offset {0} -----".format(offset,CR)
        #print (seq)
        return seq
Beispiel #46
0
 def _close(self, request):
     buffer = QBuffer(self)
     buffer.setData(
         b"<html><head><script>window.close();</script></head></html>")
     request.reply(b"text/html", buffer)
     self.parent().close()
    def responseComplete(self):
        request = self.serverInterface().requestHandler()
        params = request.parameterMap()

        # SERVICE=RENDERGEOJSON -- we are taking over
        if params.get('SERVICE', '').upper() == 'RENDERGEOJSON':
            request.clear()
            try:
                # Parse parameters
                geojson = params.get('GEOJSON')
                if not geojson:
                    raise ParameterError('Parameter GEOJSON must be set.')

                style = params.get('STYLE')
                if not style:
                    raise ParameterError('Parameter STYLE must be set.')

                try:
                    width = int(params.get('WIDTH'))
                except TypeError:
                    raise ParameterError('Parameter WIDTH must be integer.')
                try:
                    height = int(params.get('HEIGHT'))
                except TypeError:
                    raise ParameterError('Parameter HEIGHT must be integer.')

                try:
                    dpi = int(params.get('DPI', 96))
                except TypeError:
                    raise ParameterError('Parameter DPI must be integer.')

                try:
                    minx, miny, maxx, maxy = params.get('BBOX').split(',')
                    bbox = QgsRectangle(float(minx), float(miny), float(maxx),
                                        float(maxy))
                except (ValueError, AttributeError):
                    raise ParameterError(
                        'Parameter BBOX must be specified in the form `min_x,min_y,max_x,max_y`.'
                    )

                url = geojson
                geojson_file_name = self._resolve_url(geojson)

                if '$type' in style:
                    polygon_style = self._resolve_url(
                        style.replace('$type', 'polygons'))
                    line_style = self._resolve_url(
                        style.replace('$type', 'lines'))
                    point_style = self._resolve_url(
                        style.replace('$type', 'points'))
                else:
                    polygon_style = self._resolve_url(style)
                    line_style = polygon_style
                    point_style = polygon_style

                polygon_layer = QgsVectorLayer(
                    geojson_file_name + '|geometrytype=Polygon', 'polygons',
                    'ogr')
                self._load_style(polygon_layer, polygon_style)
                line_layer = QgsVectorLayer(
                    geojson_file_name + '|geometrytype=Line', 'lines', 'ogr')
                self._load_style(line_layer, line_style)
                point_layer = QgsVectorLayer(
                    geojson_file_name + '|geometrytype=Point', 'points', 'ogr')
                self._load_style(point_layer, point_style)

                settings = QgsMapSettings()
                settings.setOutputSize(QSize(width, height))
                settings.setOutputDpi(dpi)
                settings.setExtent(bbox)
                settings.setLayers([polygon_layer, line_layer, point_layer])
                settings.setBackgroundColor(QColor(Qt.transparent))
                renderer = QgsMapRendererParallelJob(settings)

                event_loop = QEventLoop()
                renderer.finished.connect(event_loop.quit)
                renderer.start()

                event_loop.exec_()

                img = renderer.renderedImage()
                img.setDotsPerMeterX(dpi * 39.37)
                img.setDotsPerMeterY(dpi * 39.37)
                image_data = QByteArray()
                buf = QBuffer(image_data)
                buf.open(QIODevice.WriteOnly)
                img.save(buf, 'PNG')

                request.setResponseHeader('Content-type', 'image/png')
                request.appendBody(image_data)
            except ParameterError as e:
                QgsMessageLog.logMessage(
                    "RenderGeojson.responseComplete :: ParameterError")
                request.setResponseHeader('Content-type', 'text/plain')
                request.appendBody(str(e).encode('utf-8'))
            except:
                QgsMessageLog.logMessage(
                    "RenderGeojson.responseComplete :: Exception")
                QgsMessageLog.logMessage(
                    "RenderGeojson.responseComplete ::   {}".format(
                        traceback.format_exc()))
                request.setResponseHeader('Content-type', 'text/plain')
                request.appendBody(b'Unhandled error')
                request.appendBody(traceback.format_exc().encode('utf-8'))
Beispiel #48
0
def base64image(image):
    ba = QByteArray()
    buffer = QBuffer(ba)
    buffer.open(QIODevice.WriteOnly)
    image.save(buffer, "PNG")
    return "data:image/png;base64," + ba.toBase64().data().decode("ascii")
Beispiel #49
0
class HelpSchemeReply(QIODevice):
    """
    Class implementing a reply for a requested qthelp: page.

    @signal closed emitted to signal that the web engine has read
        the data

    see: https://fossies.org/linux/eric6/eric/WebBrowser/Network/QtHelpSchemeHandler.py
    All credits for this class go to:
    Detlev Offenbach, the developer of The Eric Python IDE(https://eric-ide.python-projects.org)

    """
    closed = pyqtSignal()

    def __init__(self, job, engine, parent=None):
        """
        Constructor

        @param job reference to the URL request
        @type QWebEngineUrlRequestJob
        @param engine reference to the help engine
        @type QHelpEngine
        @param parent reference to the parent object
        @type QObject
        """
        super(HelpSchemeReply, self).__init__(parent)

        url = job.requestUrl()
        strUrl = url.toString()

        self.__buffer = QBuffer()

        # For some reason the url to load maybe wrong (passed from web engine)
        # though the css file and the references inside should work that way.
        # One possible problem might be that the css is loaded at the same
        # level as the html, thus a path inside the css like
        # (../images/foo.png) might cd out of the virtual folder
        if not engine.findFile(url).isValid():
            if strUrl.startswith(QtHelp_DOCROOT):
                newUrl = job.requestUrl()
                if not newUrl.path().startswith("/qdoc/"):
                    newUrl.setPath("/qdoc" + newUrl.path())
                    url = newUrl
                    strUrl = url.toString()

        self.__mimeType = mimetypes.guess_type(strUrl)[0]
        if self.__mimeType is None:
            # do our own (limited) guessing
            self.__mimeType = self.__mimeFromUrl(url)

        if engine.findFile(url).isValid():
            data = engine.fileData(url)
        else:
            data = QByteArray(self.tr(
                """<html>"""
                """<head><title>Error 404...</title></head>"""
                """<body><div align="center"><br><br>"""
                """<h1>The page could not be found</h1><br>"""
                """<h3>'{0}'</h3></div></body>"""
                """</html>""").format(strUrl)
                              .encode("utf-8"))

        self.__buffer.setData(data)
        self.__buffer.open(QIODevice.ReadOnly)
        self.open(QIODevice.ReadOnly)

    def bytesAvailable(self):
        """
        Public method to get the number of available bytes.

        @return number of available bytes
        @rtype int
        """
        return self.__buffer.bytesAvailable()

    def readData(self, maxlen):
        """
        Public method to retrieve data from the reply object.

        @param maxlen maximum number of bytes to read (integer)
        @return string containing the data (bytes)
        """
        return self.__buffer.read(maxlen)

    def close(self):
        """
        Public method used to cloase the reply.
        """
        super(HelpSchemeReply, self).close()
        self.closed.emit()

    def __mimeFromUrl(self, url):
        """
        Private method to guess the mime type given an URL.

        @param url URL to guess the mime type from (QUrl)
        @return mime type for the given URL (string)
        """
        path = url.path()
        ext = os.path.splitext(path)[1].lower()
        if ext in ExtensionMap:
            return ExtensionMap[ext]
        else:
            return "application/octet-stream"

    def mimeType(self):
        """
        Public method to get the reply mime type.

        @return mime type of the reply
        @rtype bytes
        """
        return self.__mimeType.encode("utf-8")
Beispiel #50
0
class MainWindow(QMainWindow):
    def __init__(self, wav_path):
        QMainWindow.__init__(self)
        self.resize(350, 250)
        self.setWindowTitle('MainWindow')

        self._setLayout()
        self.status_bar = self.statusBar()

        self.wav_path = wav_path
        self.params = utils.read_wav_info(wav_path)
        self.duration = self.params.nframes / self.params.framerate

        self.output = utils.get_audio_output(self.params)
        self.output.stateChanged.connect(self.state_checkpoint)
        self.output.setNotifyInterval(20)

        self.output.notify.connect(self.notified)

        self.loop_button.clicked.connect(self.switch_loop)
        self.play_button.clicked.connect(self.play_pause)
        self.random_button.clicked.connect(self.set_random_region)
        self.export_button.clicked.connect(self.export_region)

        self.command_edit.returnPressed.connect(self.command_entered)

        self.loop_enabled = False

        self.buffer = QBuffer()

        self.region = None
        self.set_region((0, REG_SECONDS * self.params.framerate))
        # self.set_random_region()

    def _setLayout(self):
        widget = QtWidgets.QWidget()

        grid = QtWidgets.QGridLayout(widget)
        self.progressBar = QtWidgets.QProgressBar(widget)
        self.progressBar.setRange(0, 100)
        self.progressBar.setValue(0)
        self.progressBar.setTextVisible(True)

        self.loop_button = QtWidgets.QPushButton('Loop', widget)
        self.loop_button.setCheckable(True)
        self.play_button = QtWidgets.QPushButton('Play | Stop', widget)
        self.random_button = QtWidgets.QPushButton('Random', widget)
        self.command_edit = QtWidgets.QLineEdit('')
        self.export_button = QtWidgets.QPushButton('Export', widget)

        grid.addWidget(self.progressBar, 0, 0, 1, 3)
        grid.addWidget(self.loop_button, 1, 0)
        grid.addWidget(self.play_button, 1, 1)
        grid.addWidget(self.random_button, 1, 2)
        grid.addWidget(self.command_edit, 2, 1)
        grid.addWidget(self.export_button, 2, 2)

        widget.setLayout(grid)
        self.setCentralWidget(widget)

    def play(self):
        """
        Play from the beginning.
        """
        if self.buffer.isOpen():
            state = self.output.state()
            if state != QAudio.StoppedState:
                self.output.stop()
            if sys.platform == 'darwin':
                self.buffer.close()
                self.buffer.open(QIODevice.ReadOnly)
            else:
                # I found this way does not works on OS X
                self.buffer.seek(0)
        else:
            # Load from file
            self.buffer.open(QIODevice.ReadOnly)
        self.output.start(self.buffer)

    def play_pause(self):
        """
        Play or pause based on audio output state.
        """
        state = self.output.state()
        if state == QAudio.ActiveState:  # playing
            # pause playback
            self.output.suspend()
        elif state == QAudio.SuspendedState:  # paused
            # resume playback
            self.output.resume()
        elif state == QAudio.StoppedState or state == QAudio.IdleState:
            self.play()

    def stop(self):
        """
        Stop playback.
        """
        state = self.output.state()
        if state != QAudio.StoppedState:
            self.output.stop()
            if sys.platform == 'darwin':
                self.buffer.close()

    def switch_loop(self):
        self.loop_enabled = not self.loop_enabled

    def state_checkpoint(self):
        """
        React to AudioOutput state change.
        Loop if enabled.
        """
        # Loop implementation
        state = self.output.state()
        if state == QAudio.ActiveState:
            print(state, '== Active')
        elif state == QAudio.SuspendedState:
            print(state, '== Suspended')
        elif state == QAudio.IdleState:
            print(state, '== Idle')
            if self.loop_enabled:
                self.play()
            else:
                self.stop()
        elif state == QAudio.StoppedState:
            print(state, '== Stopped')

    def notified(self):
        start_time = self.region[0] / self.params.framerate
        playing_time = self.output.processedUSecs() / 1000000 + start_time
        self.progressBar.setValue(playing_time * 100 / self.duration)
        self.status_bar.showMessage(str(timedelta(seconds=playing_time))[:-3])

    def set_region(self, region):
        """
        Put the playback start position to `position`.
        """
        # avoid segfault if changing region during playback
        self.stop()

        position, end = region
        position = max(0, min(position, end))  # don't start before 0
        end = min(self.params.nframes, end)  # don't set end after days!
        self.region = position, end
        print('set_region -> {:,}-{:,}'.format(*self.region))
        print('region times: {}-{} (duration={})'.format(*self.region_timedeltas()))
        frame_to_read = end - position

        wav = wave.open(self.wav_path)
        wav.setpos(position)
        # we need to reinit buffer since the region could be shorter than before
        self.buffer = QBuffer()
        self.buffer.writeData(wav.readframes(frame_to_read))
        wav.close()

        start_time = position / self.params.framerate
        self.progressBar.setValue(start_time * 100 / self.duration)
        self.status_bar.showMessage(str(timedelta(seconds=start_time))[:-3])

    @property
    def reg_nframes(self):
        return self.region[1] - self.region[0]

    def set_random_region(self):
        """
        Choose a random position and set playback start from there.
        """
        try:
            position = random.randrange(self.params.nframes - self.reg_nframes)
        except ValueError:
            print('Cannot move position randomly. Please shorten the region.')
            position = 0

        end = position + self.reg_nframes
        print('Random region: {:.2f}-{:.2f}'.format(
            position / self.params.framerate, end / self.params.framerate)
        )
        self.set_region((position, end))

    def region_timedeltas(self):
        """Return start, end and duration timedeltas"""
        start, end = self.region
        start_timedelta = timedelta(seconds=start / self.params.framerate)
        end_timedelta = timedelta(seconds=end / self.params.framerate)
        return start_timedelta, end_timedelta, (end_timedelta - start_timedelta)

    def command_entered(self):
        """
        Change region boundaries with Blender-like syntax.

        Examples:
        "l-0.5" ==> move start position 0.5 s before
        "r1"    ==> move stop position 1 seconds after
        """
        command = self.command_edit.text()
        try:
            lr, delta = utils.parse_command(command)
        except (IndexError, ValueError) as err:
            print(err)
            return

        start, end = self.region
        if lr == 'l':
            start = int(start + delta * self.params.framerate)
            print('New start: {}'.format(timedelta(seconds=(start / self.params.framerate))))
        elif lr == 'r':
            end = int(end + delta * self.params.framerate)
            print('New end: {}'.format(timedelta(seconds=(end / self.params.framerate))))

        self.set_region((start, end))
        self.command_edit.setText('')

        # feature: restart immediately after command is entered
        self.play()

    def export_region(self):
        """
        Export the current region.
        """
        start, stop = self.region
        wav_filepath = self.wav_path[:-4] + '[{}-{}].wav'.format(start, stop)
        with wave.open(wav_filepath, 'wb') as wave_write:
            wave_write.setparams(self.params)
            wave_write.writeframes(self.buffer.data())
        print(wav_filepath, 'created')
Beispiel #51
0
    def saveBookInfo(self):
        selected_items = self.treeFileList.selectedItems()
        if len(selected_items) == 1:
            QApplication.setOverrideCursor(Qt.BusyCursor)

            item = selected_items[0]
            meta = Fb2Meta(item.text(2))
            meta.get()

            if self.book_cover:
                data = QByteArray()
                buf = QBuffer(data)
                self.book_cover.save(buf, 'JPG')
                meta.coverdata = bytes(buf.buffer())
                if not meta.coverpage:
                    meta.coverpage = 'cover.jpg'
                    meta.coverpage_href = '{http://www.w3.org/1999/xlink}href'
            else:
                meta.coverpage = ''
                meta.coverdata = None

            meta.set_authors(self.editAuthor.text())
            meta.book_title = self.editTitle.text()
            meta.set_series(self.editSeries.text(),
                            self.editSeriesNumber.text())
            meta.lang = self.editBookLanguage.text()
            meta.write()

            item.setText(0, meta.book_title)
            item.setText(1, meta.get_autors())

            QApplication.restoreOverrideCursor()
        elif len(selected_items) > 1:
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Question)
            msg.setWindowTitle(_translate('fb2mobi', 'Save'))
            msg.setText(
                _translate('fb2mobi', 'Save changes in selected files?'))
            msg.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
            if msg.exec_() == QMessageBox.Save:
                QApplication.setOverrideCursor(Qt.BusyCursor)

                for item in selected_items:
                    meta = Fb2Meta(item.text(2))
                    meta.get()
                    (series, series_number) = meta.get_first_series()
                    authors = meta.get_autors()
                    if self.editAuthor.text():
                        authors = self.editAuthor.text()
                    if self.editSeries.text():
                        series = self.editSeries.text()

                    meta.set_authors(authors)
                    meta.set_series(series, series_number)
                    if self.editBookLanguage.text():
                        meta.lang = self.editBookLanguage.text()
                    meta.write()

                    item.setText(0, meta.book_title)
                    item.setText(1, meta.get_autors())

                QApplication.restoreOverrideCursor()
Beispiel #52
0
def run_api():
	# pdf = Poppler.Document()
	# page = Poppler.Page()
	pdf = 0
	page = 0
	image = QImage()
	byte_data = QByteArray()

	color_theme = 'light'  #allowed color themes: 'light','dark','sepia'
	
	while True:
		s = input()
		tokens = s.split(' ')

		if tokens[0] == 'open':  #open a pdf file
			pdf = Poppler.Document.load(tokens[1])
			pdf.setRenderHint(Poppler.Document.TextAntialiasing)

		if tokens[0] == 'page':  #open a page of the current pdf
			page = pdf.page(tokens[1])

		if tokens[0] == 'pages':  #returns number of pages
			print(pdf.numPages())

		if tokens[0] == 'color': #set color theme
			color_theme = tokens[1]

		if tokens[0] == 'textlist':  #outputs textlist as a json file
			textlist = page.textList()

			textlist_json = []
			for text in textlist:
				bb = text.boundingBox()
				d = {'text': text.text(), 'x': bb.x(), 'y': bb.y(), 'width': bb.width(), 'height': bb.height()}
				textlist_json.append(d)

			print(json.dumps(textlist_json))

		if tokens[0] == 'render': #output pixel data to stdout
			image = page.renderToImage(3 * 72, 3 * 72, -1, -1, -1, -1)
			print(image.format())
			if color_theme == 'dark':
				for x in range(image.width()):
					for y in range(image.height()):
						rgb = image.pixelColor(x, y)
						rgb.setRed(int(linear_interpolation(234, 68, rgb.red() / 255)))
						rgb.setGreen(int(linear_interpolation(234, 68, rgb.green() / 255)))
						rgb.setBlue(int(linear_interpolation(234, 68, rgb.blue() / 255)))
						image.setPixelColor(x, y, rgb)
						
			# print(image.data)
			# bits = image.bits()
			# byte_data.fromRawData(image.data)
			# print(byte_data)
			ba = QByteArray()
			buffer  = QBuffer(ba)
			buffer.open(QIODevice.WriteOnly)
			image.save(buffer, "PNG")  # writes image into ba in PNG format
			ba2 = buffer.data()
			for i in ba.
			
			bits = image.constBits()
			bits.setsize(image.width() * image.height() * 4)
			print(str(bits))
			print(dir(bits))
			print(bits.asarray())
			print(str(bits.asarray()))
			imgPtr = c_void_p(bits.__int__())
			print(dir(imgPtr))
			# for i in range(len(bits)):
				# print(bits[i])
			# print(image.constBits()[0])
			# print(bits)
			# print(type(bits))
			# for i in range(image.width()):
			# 	for j in range(image.height()):
			# 		# print(image.pixel(i, j))
			# 		print(bits[i])
			# 		# color = QColor(image.pixel(i,j))
			# 		# print(image.pixel(i,j).red(), image.pixel(i,j).green(), image.pixel(i,j).blue())	

		if tokens[0] == 'toc':
			toc = pdf.toc()
Beispiel #53
0
    def perform_request(self, endpoint, read_callback, data="", method='GET', capture_errors=True):
        """
        Perform a HTTP request.
        :param endpoint: the endpoint to call (i.e. "statistics")
        :param read_callback: the callback to be called with result info when we have the data
        :param data: optional POST data to be sent with the request
        :param method: the HTTP verb (GET/POST/PUT/PATCH)
        :param capture_errors: whether errors should be handled by this class (defaults to True)
        """
        performed_requests[self.request_id] = [endpoint, method, data, time(), -1]
        performed_requests_ids.append(self.request_id)
        if len(performed_requests_ids) > 200:
            del performed_requests[performed_requests_ids.pop(0)]
        url = self.base_url + endpoint

        if method == 'GET':
            buf = QBuffer()
            buf.setData(data)
            buf.open(QIODevice.ReadOnly)
            get_request = QNetworkRequest(QUrl(url))
            self.reply = self.sendCustomRequest(get_request, "GET", buf)
            buf.setParent(self.reply)
        elif method == 'PATCH':
            buf = QBuffer()
            buf.setData(data)
            buf.open(QIODevice.ReadOnly)
            patch_request = QNetworkRequest(QUrl(url))
            self.reply = self.sendCustomRequest(patch_request, "PATCH", buf)
            buf.setParent(self.reply)
        elif method == 'PUT':
            request = QNetworkRequest(QUrl(url))
            request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
            self.reply = self.put(request, data)
        elif method == 'DELETE':
            buf = QBuffer()
            buf.setData(data)
            buf.open(QIODevice.ReadOnly)
            delete_request = QNetworkRequest(QUrl(url))
            self.reply = self.sendCustomRequest(delete_request, "DELETE", buf)
            buf.setParent(self.reply)
        elif method == 'POST':
            request = QNetworkRequest(QUrl(url))
            request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
            self.reply = self.post(request, data)

        if read_callback:
            self.received_json.connect(read_callback)

        self.finished.connect(lambda reply: self.on_finished(reply, capture_errors))
Beispiel #54
0
    def write(self, stream, nodes, mode=MeshWriter.OutputMode.TextMode):
        """Writes the g-code for the entire scene to a stream.

        Note that even though the function accepts a collection of nodes, the
        entire scene is always written to the file since it is not possible to
        separate the g-code for just specific nodes.

        :param stream: The stream to write the g-code to.
        :param nodes: This is ignored.
        :param mode: Additional information on how to format the g-code in the
            file. This must always be text mode.
        """

        if mode != MeshWriter.OutputMode.TextMode:
            Logger.log("e",
                       "SnapmakerGCodeWriter does not support non-text mode.")
            self.setInformation(
                catalog.i18nc(
                    "@error:not supported",
                    "SnapmakerGCodeWriter does not support non-text mode."))
            return False

        active_build_plate = Application.getInstance().getMultiBuildPlateModel(
        ).activeBuildPlate
        scene = Application.getInstance().getController().getScene()
        if not hasattr(scene, "gcode_dict"):
            self.setInformation(
                catalog.i18nc("@warning:status",
                              "Please prepare G-code before exporting."))
            return False
        gcode_dict = getattr(scene, "gcode_dict")
        gcode_list = gcode_dict.get(active_build_plate, None)

        # Get some vars (I cannot find the correct value)
        printTemp = None
        bedTemp = None
        for x in gcode_list:
            if ("M190" in x or "M140" in x) and bedTemp is None:
                for y in re.findall(r"(M140|M190) S(\d+)", x):
                    #Logger.log("d","Bed:" + y[1])
                    bedTemp = y[1]
                    break
            if ("M109" in x or "M104" in x) and printTemp is None:
                for y in re.findall(r"(M109|M104) S(\d+)", x):
                    #Logger.log("d","Extruder:" + y[1])
                    printTemp = y[1]
                    break
            if printTemp is not None and bedTemp is not None:
                break
        print_info = Application.getInstance().getPrintInformation()
        feature_times = print_info.getFeaturePrintTimes()
        estiTime = 0  #in Seconds
        for x in feature_times:
            #Logger.log("d",x+":"+str(int(feature_times[x])) + " Seconds")
            estiTime += int(feature_times[x])
        # Generate snapshot
        self.snapshot = self._createSnapshot()
        Logger.log("d", "Snapshot created.")
        thumbnail_buffer = QBuffer()
        thumbnail_buffer.open(QBuffer.ReadWrite)
        thumbnail_image = self._snapshot
        thumbnail_image.save(thumbnail_buffer, "PNG")
        base64_bytes = base64.b64encode(thumbnail_buffer.data())
        base64_message = base64_bytes.decode('ascii')
        thumbnail_buffer.close()
        # Start header
        stream.write(";Header Start\n\n")
        gcode_buffer = ""
        header_buffer = False
        model_line_count = 0
        if gcode_list is not None:
            has_settings = False
            for gcode in gcode_list:
                if gcode[:len(self._setting_keyword)] == self._setting_keyword:
                    has_settings = True
                # Move FLAVOR/TIME/... block to top
                if "FLAVOR" not in gcode:
                    model_line_count += len(gcode.splitlines(
                    ))  # Add lines to model_line_count for header
                    gcode_buffer += gcode + '\n'  # Add extra newline for each layer, for readability of gcode
                else:
                    # Split header lines and write to buffer
                    header_buffer = gcode.splitlines(keepends=True)
            # Combine everything
            stream.write(header_buffer[0])  # FLAVOR
            stream.write(header_buffer[1])  # TIME
            stream.write(header_buffer[2])  # Filament used
            stream.write(header_buffer[3])  # Layer height
            stream.write("\n\n;header_type: 3dp\n")
            stream.write(";thumbnail: data:image/png;base64," +
                         base64_message + "\n")
            stream.write(";file_total_lines: " + str(model_line_count) + "\n")
            stream.write(";estimated_time(s): " + str(estiTime) + "\n")
            stream.write(";nozzle_temperature(°C): " + str(printTemp) + "\n")
            stream.write(";build_plate_temperature(°C): " + str(bedTemp) +
                         "\n")
            stream.write(header_buffer[7].replace('MAXX:',
                                                  'max_x(mm): '))  # max_x
            stream.write(header_buffer[8].replace('MAXY:',
                                                  'max_y(mm): '))  # max_y
            stream.write(header_buffer[9].replace('MAXZ:',
                                                  'max_z(mm): '))  # max_z
            stream.write(header_buffer[4].replace('MINX:',
                                                  'min_x(mm): '))  # min_x
            stream.write(header_buffer[5].replace('MINY:',
                                                  'min_y(mm): '))  # min_y
            stream.write(header_buffer[6].replace('MINZ:',
                                                  'min_z(mm): '))  # min_z
            stream.write("\n;Header End\n\n")
            # Add some useful comments, conform Luban generated code, and/or what I deem usefull
            gcode_buffer = re.sub(r"(M109 S\d+)",
                                  r"\1 ;Wait for Hotend Temperature",
                                  gcode_buffer)
            gcode_buffer = re.sub(r"(M190 S\d+)",
                                  r"\1 ;Wait for Bed Temperature",
                                  gcode_buffer)
            gcode_buffer = re.sub(r"(G92 E0)",
                                  r"\1 ;Reset the extruder's origin/length",
                                  gcode_buffer)
            stream.write(gcode_buffer)
            # Serialise the current container stack and put it at the end of the file.
            if not has_settings:
                settings = self._serialiseSettings(
                    Application.getInstance().getGlobalContainerStack())
                stream.write(settings)
            return True

        self.setInformation(
            catalog.i18nc("@warning:status",
                          "Please prepare G-code before exporting."))
        return False
    def __init__(self, view):
        self.view = view
        self.buffer = QBuffer()

        self.network_manager = QNetworkAccessManager(self.view)
        self.network_manager.finished.connect(self.on_received_response)
Beispiel #56
0
    def html(self):

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # create start to basic html format
        html = """
            <!DOCTYPE html>
            <html>
            <head>
            </head>
            <style>
            * {
                font-size: 75%;
                font-family: "Times New Roman", Times, serif;
                }
            th {
                text-align: left;
            }
            </style>
            <body>
            """

        # add title information
        html = html + ("<H1>" + self.lblLocation.text() + "</H1>")

        html = html + ("<H3>" + self.lblDateRange.text() + "</H3>")

        html = html + ("<H3>" + self.lblDetails.text() + "</H3>")

        html = html + ("<H3>" + self.lblLocationsVisited.text() + "</H3>")

        html = html + ("<H3>" + self.lblTopSpeciesSeen.text() + "</H3>")

        # grab the map image from the map tap
        # process it into a byte array and encode it
        # so we can insert it inline into the html
        myPixmap = self.webMap.grab()
        myPixmap = myPixmap.scaledToWidth(600, Qt.SmoothTransformation)

        myByteArray = QByteArray()
        myBuffer = QBuffer(myByteArray)
        myBuffer.open(QIODevice.WriteOnly)
        myPixmap.save(myBuffer, "PNG")

        encodedImage = base64.b64encode(myByteArray)

        html = html + ("""
        <img src="data:image/png;base64, 
        """)

        html = html + str(encodedImage)[1:]

        html = html + ("""        
        "  />
        """)

        html = html + ("<H4>" + "Species" + "</H4>")

        html = html + ("<font size='2'>" + "<table width='100%'>" + " <tr>")

        html = html + ("<th>" + "Species" + "</th>" + "<th>" + "First" +
                       "</th> " + "<th></th> " + "<th>" + "Latest" + "</th>" +
                       "</tr>")

        for r in range(self.tblSpecies.rowCount()):
            html = html + (
                "<tr>" + "<td>" + self.tblSpecies.item(r, 1).text() + "</td>" +
                "<td>" + self.tblSpecies.item(r, 2).text() + "</td>" + "<td>" +
                "  " + "</td>" + "<td>" + self.tblSpecies.item(r, 3).text() +
                "</td>" + "</tr>")
        html = html + "</table>"

        html = html + ("<H4>" + "Dates" + "</H4>")

        html = html + ("<font size='2'>" + "<p>")

        # loopthrough the dates listed in lstDates
        # create a filter unique to each date
        # and get species for that date
        for r in range(self.lstDates.count()):
            html = html + ("<b>" + self.lstDates.item(r).text() + "</b>")

            # create filter set to our current location
            filter = deepcopy(self.filter)
            filter.setStartDate(self.lstDates.item(r).text())
            filter.setEndDate(self.lstDates.item(r).text())

            species = self.mdiParent.db.GetSpecies(filter)

            html = html + ("<br>" + "<table width='100%'>" + "<tr>")

            # set up counter R to start a new row after listing each 3 species
            R = 1
            for s in species:
                html = html + ("<td>" + s + "</td>")
                if R == 3:
                    html = html + ("</tr>" + "<tr>")
                    R = 0
                R = R + 1

            html = html + ("<br>" + "<br>" + "</table>")

        html = html + (
            "<H4>" + "Locations" + "</H4>" + "<p>" +
            "Asterisks indicate species seen only at listed location.")

        # loopthrough the locations listed in lstLocations
        # create a filter unique to each location
        # and get species for that date
        for r in range(self.lstLocations.count()):
            html = html + ("<b>" + self.lstLocations.item(r).text() + "</b>")

            # create filter set to our current location
            filter = deepcopy(self.filter)
            filter.setLocationType("Location")
            filter.setLocationName(self.lstLocations.item(r).text())

            species = self.mdiParent.db.GetSpecies(filter)

            uniqueSpecies = self.mdiParent.db.GetUniqueSpeciesForLocation(
                self.filter,
                self.lstLocations.item(r).text(), species,
                self.filteredSightingList)

            html = html + ("<br>" + "<table width='100%'>" + "<tr>")

            # set up counter R to start a new row after listing each 3 species
            R = 1
            for s in species:

                if s in uniqueSpecies:
                    s = s + "*"

                html = html + ("<td>" + s + "</td>")
                if R == 3:
                    html = html + ("</tr>" + "<tr>")
                    R = 0
                R = R + 1

            html = html + ("<br>" + "<br>" + "</table>")

        html = html + ("<p>" + "<H4>" + "New Life Species" + "</H4>" + "<p>" +
                       "<table width='100%'>"
                       "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.lstNewLifeSpecies.count() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:

            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.lstNewLifeSpecies.count()):

                html = html + ("<td>" + self.lstNewLifeSpecies.item(r).text() +
                               "</td>")

                if R == 3:
                    html = html + ("</tr>" + "<tr>")
                    R = 0

                R = R + 1

            html = html + ("<br>" + "<br>" + "</table>")

        # set up New Year Species
        html = html + ("<p>" + "<H4>" + "New Year Species" + "</H4>" + "<p>" +
                       "<table width='100%'>" + "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.tblNewYearSpecies.rowCount() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:
            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.tblNewYearSpecies.rowCount()):

                html = html + (
                    "<td>" + self.tblNewYearSpecies.item(r, 1).text() + " (" +
                    self.tblNewYearSpecies.item(r, 0).text() + ")" + "</td>")

                if R == 3:
                    html = html + ("</tr>" "<tr>")
                    R = 0

                R = R + 1

            html = html + ("</tr>" + "</table>")

        # set up New Month Species
        html = html + ("<p>" + "<H4>" + "New Month Species" + "</H4>" + "<p>" +
                       "<table width='100%'>" + "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.tblNewMonthSpecies.rowCount() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:

            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.tblNewMonthSpecies.rowCount()):

                html = html + (
                    "<td>" + self.tblNewMonthSpecies.item(r, 1).text() + " (" +
                    self.tblNewMonthSpecies.item(r, 0).text() + ")" + "</td>")

                if R == 3:
                    html = html + ("</tr>" "<tr>")
                    R = 0

                R = R + 1

            html = html + ("</tr>" + "</table>")

        # set up New Country Species
        html = html + ("<p>" + "<H4>" + "New Country Species" + "</H4>" +
                       "<p>" + "<table width='100%'>" + "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.tblNewCountrySpecies.rowCount() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:

            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.tblNewCountrySpecies.rowCount()):

                html = html + ("<td>" + self.tblNewCountrySpecies.item(
                    r, 1).text() + " (" + self.tblNewCountrySpecies.item(
                        r, 0).text() + ")" + "</td>")

                if R == 2:
                    html = html + ("</tr>" "<tr>")
                    R = 0

                R = R + 1

            html = html + ("</tr>" + "</table>")

        html = html + ("<font size>" + "</body>" + "</html>")

        # set up New State Species
        html = html + ("<p>" + "<H4>" + "New State Species" + "</H4>" + "<p>" +
                       "<table width='100%'>" + "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.tblNewStateSpecies.rowCount() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:

            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.tblNewStateSpecies.rowCount()):

                html = html + (
                    "<td>" + self.tblNewStateSpecies.item(r, 1).text() + " (" +
                    self.tblNewStateSpecies.item(r, 0).text() + ")" + "</td>")

                if R == 2:
                    html = html + ("</tr>" "<tr>")
                    R = 0

                R = R + 1

            html = html + ("</tr>" + "</table>")

        # set up New County Species
        html = html + ("<p>" + "<H4>" + "New County Species" + "</H4>" +
                       "<p>" + "<table width='100%'>" + "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.tblNewCountySpecies.rowCount() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:

            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.tblNewCountySpecies.rowCount()):

                html = html + ("<td>" + self.tblNewCountySpecies.item(
                    r, 1).text() + " (" + self.tblNewCountySpecies.item(
                        r, 0).text() + ")" + "</td>")

                if R == 2:
                    html = html + ("</tr>" "<tr>")
                    R = 0

                R = R + 1

            html = html + ("</tr>" + "</table>")

        # set up New Location Species
        html = html + ("<p>" + "<H4>" + "New Location Species" + "</H4>" +
                       "<p>" + "<table width='100%'>" + "<tr>")

        # set up counter R to start a new row after listing each 3 species
        R = 1

        if self.tblNewLocationSpecies.rowCount() == 0:
            html = html + ("<td>" + "None" + "</td>")

        else:

            # loopthrough the species listed in lstNewLifeSpecies
            for r in range(self.tblNewLocationSpecies.rowCount()):

                html = html + ("<td>" + self.tblNewLocationSpecies.item(
                    r, 1).text() + " (" + self.tblNewLocationSpecies.item(
                        r, 0).text() + ")" + "</td>")

                if R == 2:
                    html = html + ("</tr>" "<tr>")
                    R = 0

                R = R + 1

            html = html + ("</tr>" + "</table>")

        html = html + ("<font size>" + "</body>" + "</html>")

        QApplication.restoreOverrideCursor()

        return (html)
Beispiel #57
0
    def write(self, stream, nodes, mode=MeshWriter.OutputMode.BinaryMode):
        archive = VirtualFile()
        archive.openStream(stream, "application/x-ufp", OpenMode.WriteOnly)

        #Store the g-code from the scene.
        archive.addContentType(extension="gcode", mime_type="text/x-gcode")
        gcode_textio = StringIO()  #We have to convert the g-code into bytes.
        gcode_writer = cast(
            MeshWriter,
            PluginRegistry.getInstance().getPluginObject("GCodeWriter"))
        success = gcode_writer.write(gcode_textio, None)
        if not success:  #Writing the g-code failed. Then I can also not write the gzipped g-code.
            self.setInformation(gcode_writer.getInformation())
            return False
        gcode = archive.getStream("/3D/model.gcode")
        gcode.write(gcode_textio.getvalue().encode("UTF-8"))
        archive.addRelation(
            virtual_path="/3D/model.gcode",
            relation_type=
            "http://schemas.ultimaker.org/package/2018/relationships/gcode")

        self._createSnapshot()

        #Store the thumbnail.
        if self._snapshot:
            archive.addContentType(extension="png", mime_type="image/png")
            thumbnail = archive.getStream("/Metadata/thumbnail.png")

            thumbnail_buffer = QBuffer()
            thumbnail_buffer.open(QBuffer.ReadWrite)
            thumbnail_image = self._snapshot
            thumbnail_image.save(thumbnail_buffer, "PNG")

            thumbnail.write(thumbnail_buffer.data())
            archive.addRelation(
                virtual_path="/Metadata/thumbnail.png",
                relation_type=
                "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail",
                origin="/3D/model.gcode")
        else:
            Logger.log("d", "Thumbnail not created, cannot save it")

        # Store the material.
        application = Application.getInstance()
        machine_manager = application.getMachineManager()
        material_manager = application.getMaterialManager()
        global_stack = machine_manager.activeMachine

        material_extension = "xml.fdm_material"
        material_mime_type = "application/x-ultimaker-material-profile"

        try:
            archive.addContentType(extension=material_extension,
                                   mime_type=material_mime_type)
        except:
            Logger.log("w", "The material extension: %s was already added",
                       material_extension)

        added_materials = []
        for extruder_stack in global_stack.extruders.values():
            material = extruder_stack.material
            try:
                material_file_name = material.getMetaData(
                )["base_file"] + ".xml.fdm_material"
            except KeyError:
                Logger.log("w", "Unable to get base_file for the material %s",
                           material.getId())
                continue
            material_file_name = "/Materials/" + material_file_name

            # The same material should not be added again.
            if material_file_name in added_materials:
                continue

            material_root_id = material.getMetaDataEntry("base_file")
            material_group = material_manager.getMaterialGroup(
                material_root_id)
            if material_group is None:
                Logger.log("e",
                           "Cannot find material container with root id [%s]",
                           material_root_id)
                return False

            material_container = material_group.root_material_node.getContainer(
            )
            try:
                serialized_material = material_container.serialize()
            except NotImplementedError:
                Logger.log(
                    "e",
                    "Unable serialize material container with root id: %s",
                    material_root_id)
                return False

            material_file = archive.getStream(material_file_name)
            material_file.write(serialized_material.encode("UTF-8"))
            archive.addRelation(
                virtual_path=material_file_name,
                relation_type=
                "http://schemas.ultimaker.org/package/2018/relationships/material",
                origin="/3D/model.gcode")

            added_materials.append(material_file_name)

        archive.close()
        return True
Beispiel #58
0
    def export_video(self):
        if not imageio:
            return QMessageBox(
                QMessageBox.Information, 'Export not available',
                'imageio and ffmpeg must be installed to export videos').exec(
                )

        location = QFileDialog.getSaveFileName(self,
                                               'Choose export location',
                                               filter='Video (*.mp4)')[0]
        if not location:
            return

        if not location.endswith('.mp4'):
            location += '.mp4'

        frame_count = int(self.duration * FPS)
        progress_box = QProgressDialog('Recording and exporting video...',
                                       'Cancel', 1, frame_count, self)
        progress_box.setWindowModality(Qt.WindowModal)
        with imageio.get_writer(location,
                                format='mp4',
                                mode='I',
                                fps=FPS,
                                quality=6) as writer:
            frame = 0
            stopped = False

            def new_event(*args):
                nonlocal frame, stopped
                try:
                    self.callback(
                        AniState(self,
                                 frame=frame,
                                 time=frame / FPS,
                                 dt=1 / FPS))
                    frame += 1
                except StopIteration:
                    stopped = True

            old = self.paintEvent
            self.paintEvent = new_event

            self.start()
            self.frame_no = 0
            for i in range(frame_count):
                progress_box.setValue(i)
                if progress_box.wasCanceled():
                    os.remove(location)
                    return

                im_bytes = QByteArray()
                buf = QBuffer(im_bytes)
                buf.open(QIODevice.WriteOnly)
                self.grab().save(buf, 'PNG', 100)  # Triggers paintEvent
                self.frame_no += 1
                writer.append_data(imageio.imread(im_bytes.data(), 'png'))
                if stopped:
                    break

        progress_box.setValue(progress_box.maximum())
        self.paintEvent = old

        return QMessageBox(
            QMessageBox.Information, 'Completed',
            'Export finished! Saved to {}'.format(location)).exec()
Beispiel #59
0
def qImgToPilRGBA(qimg):
    buf = QBuffer()
    buf.open(QBuffer.ReadWrite)
    qimg.save(buf, "PNG")
    return Image.open(io.BytesIO(buf.data().data())).convert('RGBA')