Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre programming (publicaciones antiguas, página 64)

Capturing a webpage as an image using Pyhon and Qt

En­ton­ces googleé y me en­contré con Cu­ty­Capt que usa Qt y We­bKit pa­ra con­ver­tir pá­gi­nas web en imá­ge­nes. ¡Me sir­ve!

Co­mo quie­ro usar­lo des­de una apli­ca­ción Py­Q­t, tie­ne sen­ti­do ha­cer lo mis­mo que Cu­ty­Capt ha­ce, pe­ro des­de un mó­du­lo py­thon así que acá es­tá una im­ple­men­ta­ción ra­pi­di­ta que fun­cio­na pa­ra mí, un­que ca­re­ce de mu­chos fea­tu­res de Cu­ty­Cap­t.

Con un po­co más de es­fuer­zo, pue­de guar­dar co­mo PDF o SV­G, lo que per­mi­ti­ría usar­la ca­si co­mo una pá­gi­na web de ver­da­d.

Se usa así:

python  capty.py http://www.kde.org kde.png

Y acá es­tá el có­di­go [des­car­gar cap­ty.­py]

# -*- coding: utf-8 -*-

"""This tries to do more or less the same thing as CutyCapt, but as a
python module.

This is a derived work from CutyCapt: http://cutycapt.sourceforge.net/

////////////////////////////////////////////////////////////////////
//
// CutyCapt - A Qt WebKit Web Page Rendering Capture Utility
//
// Copyright (C) 2003-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// $Id$
//
////////////////////////////////////////////////////////////////////

"""

import sys
from PyQt4 import QtCore, QtGui, QtWebKit


class Capturer(object):
    """A class to capture webpages as images"""

    def __init__(self, url, filename):
        self.url = url
        self.filename = filename
        self.saw_initial_layout = False
        self.saw_document_complete = False

    def loadFinishedSlot(self):
        self.saw_document_complete = True
        if self.saw_initial_layout and self.saw_document_complete:
            self.doCapture()

    def initialLayoutSlot(self):
        self.saw_initial_layout = True
        if self.saw_initial_layout and self.saw_document_complete:
            self.doCapture()

    def capture(self):
        """Captures url as an image to the file specified"""
        self.wb = QtWebKit.QWebPage()
        self.wb.mainFrame().setScrollBarPolicy(
            QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
        self.wb.mainFrame().setScrollBarPolicy(
            QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)

        self.wb.loadFinished.connect(self.loadFinishedSlot)
        self.wb.mainFrame().initialLayoutCompleted.connect(
            self.initialLayoutSlot)

        self.wb.mainFrame().load(QtCore.QUrl(self.url))

    def doCapture(self):
        self.wb.setViewportSize(self.wb.mainFrame().contentsSize())
        img = QtGui.QImage(self.wb.viewportSize(), QtGui.QImage.Format_ARGB32)
        painter = QtGui.QPainter(img)
        self.wb.mainFrame().render(painter)
        painter.end()
        img.save(self.filename)
        QtCore.QCoreApplication.instance().quit()

if __name__ == "__main__":
    """Run a simple capture"""
    app = QtGui.QApplication(sys.argv)
    c = Capturer(sys.argv[1], sys.argv[2])
    c.capture()
    app.exec_()

Aprendé python! Gratis! Conmigo! (una parte)

Ca­da sá­ba­do po­dés apren­der al­go de al­gu­nos de los me­jo­res pro­gra­ma­do­res Py­thon de la co­mar­ca (o de mí).

Voy a en­se­ñar vir­tua­len­v, buil­dou­t, no­se y otras co­sas el 21/8, co­sas de GUI el 25/9 y 2/10 y Py­Qt el 30/10.

¡To­do es gra­tis, y oja­lá ven­ga mu­cha gen­te!

Cro­no­gra­ma com­ple­to acá.

El software libre es bueno conmigo.

Pe­ro eso no es tan im­por­tan­te, yo po­dría ga­nar­me la vi­da ha­cien­do otra co­sa. Es­toy se­gu­ro que se­ría com­pe­ten­te pa­ra al­go, aún si no se me ocu­rre na­da en es­te mo­men­to.

Más im­por­tan­te es que me da li­ber­tad pa­ra ju­ga­r. Por lo tan­to es­te post es una es­pe­cie de re­por­te de las co­sas con las que ju­gué. No jue­gos, no son lo mío, pe­ro co­sas que ha­go por di­ver­sió­n.

Sí, al­gu­nas de es­tas sig­ni­fi­can que soy un ti­po muy ra­ro.

Li­mi­tán­do­me al úl­ti­mo par de se­ma­nas o al­go así:

Hu­bo bas­tan­te in­te­rés en Ma­ra­ve, mi edi­tor sin dis­trac­cio­nes y es por­que salió en Li­nux Jour­na­l.

Leí el ar­tícu­lo (la­men­ta­ble­men­te no pue­do po­ner un li­nk) y fué su­per po­si­ti­vo, al­gu­nas ci­ta­s:

"ma­ra­ve makes the du­ll world of text edi­ting ro­man­tic and im­mer­si­ve wi­th beau­ti­ful mi­ni­ma­lis­m"

"... it does­n't just ha­ve mi­ni­ma­lism and sim­pli­ci­ty, it has mi­ni­ma­lism and sim­pli­ci­ty com­bi­ned wi­th beau­ty and a pal­pa­ble de­sign ethi­c. ma­ra­ve has sou­l, and I lo­ve tha­t."

Así que gra­cias por la ama­bi­li­dad al au­to­r, y al­go que no­té: se en­contró con un bug enor­me y no se dio cuen­ta :-)

El icono del des­tor­ni­lla­dor de­be­ría mos­trar el diá­lo­go de con­fi­gu­ra­ció­n. Sin em­bar­go, pa­re­ce que en Ubun­tu (y tal vez en otras dis­tro­s, no lo sé) no apa­re­ce, y to­do lo que se ve es que el tex­to se mue­ve un po­co. Es­to es lo que de­be­ría ha­ber vis­to:

marave15

Yo nun­ca lo pu­de re­pro­du­ci­r, pe­ro voy a ins­ta­lar una VM de Ubun­tu pa­ra ver­lo, así que tal vez pron­to.

En co­sas re­la­cio­na­da­s, ma­ra­ve salió en una re­vis­ta ale­ma­na ha­ce un par de me­s­es, pe­ro no pu­de ob­te­ner una co­pia del ar­tícu­lo. (De pa­so: no es ra­zo­na­ble en­viar una co­pia de es­tas co­sas al au­tor del pro­gra­ma que es­tás pro­ban­do? Nin­gu­na re­vis­ta no si­quie­ra me avi­só­!)

En cual­quier ca­so, si al­guien tie­ne es­ta re­vis­ta y me pue­de de­cir que di­ce el ar­tícu­lo so­bre edi­to­res sin dis­trac­cio­nes, me va a po­ner con­ten­to:

Acá es­tá el ade­lan­to del ar­tícu­lo

Y es­ta pa­re­ce ser la re­vis­ta:

https://shop.linuxnewmedia.de/store/eh01/EH10165/de/product_image/variant/bounding_product

En cuan­to a pro­yec­tos nue­vos (sí, siem­pre ten­go pro­yec­tos nue­vo­s) me en­contré con es­te ex­ce­len­te ar­tícu­lo de Ro­ger Al­sing acer­ca de apro­xi­mar la Mo­na Li­sa con 50 po­lí­go­nos <h­ttp://­ro­ge­ral­sin­g.­co­m/2008/12/07/­ge­ne­ti­c-­pro­gra­m­min­g-e­vo­lu­tio­n-o­f-­mo­na-­li­sa/ > y, sien­do un nerd con asom­bro­sas he­rra­mien­tas de pro­gra­ma­ción a mi al­can­ce... es­cri­bí un fra­mewo­rk pa­ra pro­bar esa cla­se de al­go­rit­mo­s.

Le pu­se evo­lu­to y es­tá en http://e­vo­lu­to­.­google­co­de.­com.

Só­lo hi­ce un al­go­rit­mo muy sim­ple, ba­sa­do en trián­gu­los se­mi­trans­pa­ren­tes, pe­ro fun­cio­na... mi­ra­do con ca­ri­ño.

Se pue­de ver co­mo el ojo de­re­cho se que­da tra­ba­do en un mí­ni­mo lo­cal :-)

Evo­lu­to tie­ne una bi­blio­te­ca de al­go­rit­mos (ac­tual­men­te va­cía) y se pue­den edi­tar y rea­pli­car ins­tan­tá­nea­men­te si uno quie­rem y ver las ge­ne­ra­cio­nes cam­biar en pan­ta­lla.

Ne­ce­si­ta­ría bas­tan­te tra­ba­jo pa­ra ser un pro­gra­ma pu­li­do, pe­ro al­go es al­go.

Es­tu­ve pa­vean­do con crear un pro­gra­ma pa­ra ver pre­sen­ta­cio­nes en PDF pe­ro to­da­via le fal­ta una vi­da:

109301062

En lo que es tal vez mi pro­yec­to más es­ta­ble­ci­do, rs­t2­pdf. Co­rre­gí va­rios bugs, y le es­tá ha­cien­do fal­ta un re­lea­se:

Issue 186: El texto no rodea las imágenes cuando se especifica

Lo arre­glé con una op­ción nue­va, así que el com­por­ta­mien­to por de­fault es el mis­mo, pe­ro an­da. No que­do muy bue­no, pe­ro an­da.

Issue 307: La directiva replace no funciona en header/footer en algunos casos

Fué un pro­ble­ma muy in­te­re­san­te, muy di­ver­ti­do!

hacerlo funcionar con Sphinx 1.*

Hay una par­te que si­gue ro­ta, pe­ro lo que arre­glé no fué te­rri­ble.

Desrromper bookrest

le fal­ta mu­chí­si­mo la­bu­ro, pe­ro por lo me­nos lo que an­da­ba an­tes an­da de nue­vo. Si no sa­bés que es book­res­t, es un fron­tend grá­fi­co pa­ra rs­t2­pdf / pro­ce­sa­dor de tex­to­s, acá lo ves en ac­ció­n:

Tam­bién hi­ce va­rios re­lea­ses de mis pa­que­tes de AUR

Ade­más tra­ba­jé, y al­gu­nas otras co­sas. Bas­tan­te pro­duc­ti­vo!


Contents © 2000-2021 Roberto Alsina