Importação automática de imagens através de script

Versão em inglês.

=Básico=

Uma nova versão está disponível: Importação automática de imagens V2

Primeiramente, a razão de eu ter criado esse scripts foi para aprender alguma coisa sobre Python e para poder criar um arquivador de imagens ou álbum no Scribus. Geralmente eu uso o script para organizar as imagens digitais que eu tiro nas minhas viagens. Uma das vantagens do Scribus é que o seu formato de arquivo .sla não inclui nenhum dado de imagem, mas apenas suas referências, então, este arquivo de catálogo é relativamente pequeno. Eu irei adicionar anotações, fazer um PDF e imprimir um álbum com algumas coleções.

Inicialmente eu criei um programa em Perl a parte (scribalbum.pl) para fazer a criação fora do Scribus. O script ainda funciona, mesmo tendo sido projetado para os formatos de arquivo da versão 1.2.x. Uma de suas vantagens é a velocidade com que ele gera diversas páginas com informações. Sua desvantagem é que ele foi criado para o formato 1.2.x, ou seja, potencialmente incompatível com as novas versões (e até um tanto quanto perigoso). Ajustá-lo para gerar os documentos na nova versão é mais trabalho do que eu gostaria. Melhor carregá-lo no Scribus 1.3.x e então salvar de lá mesmo.

As implementações Python tem a vantagem de usar o próprio Scribus para criar um documento, sendo assim, enquanto o script funcionar o arquivo resultante estará atualizado. Outro benefício é a facilidade de modificação do script para ser ajustado a outras necessidades.

= Descrição =

scribalbum.pl
Eu não irei dizer nada sobre este programa. Se você conhece alguma coisa de Perl, verá que isto não é "elegante", mas faz o trabalho. Sua operação é através da linha de comando.

scribalbum.py e scribalbuma4.py
Estes scripts são similares, ambos criam um novo documento e quantas páginas forem necessárias. O scribalbum.py coloca quatro imagens desalinhadas uma das outras em uma página de tamanho carta (americana), permitindo anotações nos espaços remanescentes. Já o scribalbum4.py coloca 8 imagens por página A4, deixando pouco espaço livre restante. Ambas as versões farão um quadro de texto no canto superior esquerdo de cada página, indicando qual o diretório que a imagem está. Cada imagem possui um título indicando o nome de arquivo da imagem.

Atualização: O Gregory criou uma nova versão que elimina a necessidade do uso do Tkinter, veja a nova versão (em inglês).

Aqui estão alguns dos recursos que ambos os scripts compartilham:


 * Quando você executar o script no Scribus, duas janelas Tk aparecerão, uma branca e outra que pergunta o nome do diretório e possui caixas de marcação. Você pode usar um caminho relativo. O absoluto será mais preciso.


 * Você pode marcar um ou mais formatos de imagens que você quer. TODAS as imagens daquele tipo serão incluidas - você não pode selecionar e/ou escolher imagens individualmente. Elas aparecerão na ordem alfa-numérica no seu documento, sendo a coluna da esquerda a primeira.


 * PDFs serão importados mas somente a sua primeira página.


 * Por enquanto este script não importa SVGs. O que você tem é um quadro branco. Essa é uma das coisas na lista do meu "a fazer" (TODO).


 * Todas as imagens são ajustadas para coresponder ao tamanho do quadro, sendo o mesmo tamanho de quadro em cada script.. Ajustar um quadro para uma imagem individual é uma tarefa melhor feita no Scribus após você ter feito o arquivo. Estes scripts foram desenvolvidos para fazer o trabalho "grosso". Vamos deixar que o Scribus faça o trabalho de refino.


 * Uma vez que você tenha fornecido o diretório e selecionado os formatos das imagens, basta clicar em OK. Aguarde um tempo (durante este processo os quadros e os ícones do Scribus podem piscar).


 * Quando o script terminar, a janela TK que estava branca agora dirá: Agora clique no X no canto superior direito desta janela, significando que o X no canto da janela Tk irá a apagar. Com esta ação o script termina e o Scribus assume.


 * Neste ponto o Scribus está - em teoria - carregando o arquivo para exibição. Esse processo pode demorar até minutos dependendo do número e do tamanho das imagens, além das configurações de sua máquina (memória, processador etc).


 * Se nesse ponto o Scribus quebrar/travar, provavelmente toda a memória RAM e swap foi usada no seu sistema. Ainda não há uma proteção incluida neste script contra essa possibilidade. Se você tiver sorte, o Scribus terá salvo um arquivo de emergência começando com DocumentN..., mas, se o arquivo for grande demais, o Scribus não conseguirá o carregar, já que a memória continuará criando essa restição (o arquivo por sí só não é grande, o requerimento de memória para todas as imagens que é a fonte do problema).

= Notas adicionais = Devido a limitações desconhecidas neste instante, este script não funciona na versão Windows do Scribus; Aguarde até que o problema seja solucionado.

= Arquivos =

scribalbum.pl
Como este é um programa a parte (stand-alone), suas strings não serão traduzidas. Consulte a página em inglês para ver o código.

scribalbum.py

 * 1) !/usr/bin/env python


 * 1) Arquivo: scribalbum.py
 * 2) originado em 2005.02.13  Gregory Pittman
 * 3) modificado em  2005.02.27 - from scribalbuma4.py
 * 4) Esta versão é para o formato papel carta (E.U.A)
 * 5) Também, apenas coloca 4 imagens por página, permitindo quadros de textos (notas) entre as imagens.
 * 6) Usa o Tkinter para exibir uma caixa de entrada para o nome do diretório.
 * 7) Filtra os arquivos terminados com .jpg, .png, e assim por diante (selecionável pelo usuário)
 * 8) Nota: no momento não é possível a seleção de extensões em caixa alta
 * 9) Cria um novo documento
 * 10) Alguma das coisas a serem solucionadas: necessita de um fechamento mais elegante;
 * 11) por enquanto pede que você clique
 * 12) no X no canto superior direito do quadro raiz, mas pelo menos diz quando
 * 13) você deve.
 * 14) Eventualmente ser hábil a navegar entre diretórios, talvez mostrar uma
 * 15) Listbox (lista de seleção) para a seleção do diretório.
 * 1) Eventualmente ser hábil a navegar entre diretórios, talvez mostrar uma
 * 2) Listbox (lista de seleção) para a seleção do diretório.

from scribus import * import Tkinter import os

class ImageDialog(Tkinter.Toplevel): def __init__(self, parent): global jpg, tif, png, pdf, svg, gif Tkinter.Toplevel.__init__(self, parent, bg="#bbbbff")

Tkinter.Label(self, text='Enter the Image Directory, Click OK',bg="#bbbbff").grid(row=0,columnspan=6)

self.e = Tkinter.Entry(self) self.e.grid(row=1,columnspan=6) self.jpg = Tkinter.StringVar self.tif = Tkinter.StringVar self.png = Tkinter.StringVar self.pdf = Tkinter.StringVar self.svg = Tkinter.StringVar self.gif = Tkinter.StringVar b = Tkinter.Button(self, text='OK', bg="#55ff88", command=self.ok) b.grid(row=2,columnspan=6) self.protocol("WM_DELETE_WINDOW", self.quit) Tkinter.Label(self, text='Filters',bg="#bbbbff").grid(row=3) j = Tkinter.Checkbutton(self, text = '.jpg', variable = self.jpg,onvalue='.jpg') j.grid(row=4,column=0) t = Tkinter.Checkbutton(self, text = '.tif', variable = self.tif,onvalue='.tif') t.grid(row=4,column=2) p = Tkinter.Checkbutton(self, text = '.png', variable = self.png,onvalue='.png') p.grid(row=4, column=4) P = Tkinter.Checkbutton(self, text = '.pdf', variable = self.pdf,onvalue='.pdf') P.grid(row=5, column=0) s = Tkinter.Checkbutton(self, text = '.svg', variable = self.svg,onvalue='.svg') s.grid(row=5, column=2) g = Tkinter.Checkbutton(self, text = '.gif', variable = self.gif,onvalue='.gif') g.grid(row=5, column=4) j.select # descomente esta linha para ter uma opção padrão de configuração nos botões de checagem
 * 1)        t.select # j = .jpg, t = .tif, etc.
 * 2)        s.select
 * 3)        p.select
 * 4)        P.select
 * 5)        g.select

def ok(self): m = Tkinter.Message(root, text="Agora clique no X no canto superior direito desta janela") m.grid(row=0, columnspan=4) try: D=[] imagecount = 0 framecount = 0 filetype = [] if len(self.jpg.get) == 4: filetype.append(self.jpg.get) if len(self.tif.get) == 4: filetype.append(self.tif.get) if len(self.png.get) == 4: filetype.append(self.png.get) if len(self.pdf.get) == 4: filetype.append(self.pdf.get) if len(self.svg.get) == 4: filetype.append(self.svg.get) if len(self.gif.get) == 4: filetype.append(self.gif.get) d = os.listdir(self.e.get) for file in d:               for format in filetype: if file.endswith(format): D.append(file) D.sort xpos = (15, 310) ypos = (42, 388, 187, 533) pwidth = 288 pheight = 217
 * 1) Há 4 imagens por página; xpos e ypos são as coordenadas  x,y do canto superior esquerdo
 * 2) As coordenadas são: (15, 42),(15, 388), (310, 187), (310, 533)
 * 1) Esta proporção é a certa para fotografias (pelo menos com a minha digital Olympus)

if newDoc(PAPER_LETTER, (10,10,20,20),PORTRAIT, 1, UNIT_POINTS, NOFACINGPAGES, FIRSTPAGERIGHT): while D[imagecount]: if imagecount > 0: newPage(-1) framecount = 0 L = createText(15, 20, 200, 20) setText("Dir: " + self.e.get, L)                   setTextAlignment(ALIGN_LEFT, L)                    setFont("Luxi Sans Regular", L)                    setFontSize(10, L)                    for xframe in xpos: if D[imagecount]: f = createImage(xframe, ypos[framecount], pwidth, pheight) loadImage(self.e.get + '/' + D[imagecount], f)                               setScaleImageToFrame(scaletoframe=1, proportional=1, name=f) lenfilename = len(D[imagecount]) Lpiclen = int(5.3 * lenfilename) Lpic = createText(xframe, ypos[framecount] + 217, Lpiclen, 15) setText(D[imagecount], Lpic) setTextAlignment(ALIGN_RIGHT, Lpic) setFont("Luxi Mono Regular", Lpic) setFontSize(8, Lpic) setFillColor("White", Lpic) imagecount = imagecount + 1 framecount = framecount + 1 if D[imagecount]: f = createImage(xframe, ypos[framecount], pwidth, pheight) loadImage(self.e.get + '/' + D[imagecount], f)                               setScaleImageToFrame(scaletoframe=1, proportional=1, name=f) lenfilename = len(D[imagecount]) Lpiclen = int(5.3 * lenfilename) Lpic = createText(xframe, ypos[framecount] + 217, Lpiclen, 15) setText(D[imagecount], Lpic) setTextAlignment(ALIGN_RIGHT, Lpic) setFont("Luxi Mono Regular", Lpic) setFontSize(8, Lpic) setFillColor("White", Lpic) imagecount = imagecount + 1 framecount = framecount + 1 setRedraw(1) redrawAll self.Tkinter.Toplevel.destroy except os.error, value: Tkinter.Button(root, text=value[1], bg="#ffff55").grid(row=3, columnspan = 4)
 * 1) L é o quadro no topo de cada página que mostra o nome de diretório
 * 1) Aqui é onde nós estamos carregando as imagens na página, quadro por vez, então volta e cria uma nova página
 * 1) Lpic é o título de cada imagem com as posição e largura ajustadas
 * 2) de acordo com a largura do texto.
 * 3) Então se você mudar a fonte ou o seu tamanho, talvez você precise ajustar
 * 4) isto para um calculo aproximado.

root = Tkinter.Tk root.update

d = ImageDialog(root)

root.wait_window(d)

scribalbuma4.py

 * 1) !/usr/bin/env python


 * 1) Arquivo: scribalbuma4.py
 * 2) originado em 2005.02.13  Gregory Pittman
 * 3) modificado em  2005.02.27 - from scribalbuma4.py
 * 4) Esta versão é para o formato papel A4 (S.I.)
 * 5) Também, coloca 8 imagens por página, deixando pouco espaço para as anotações.
 * 6) Usa o Tkinter para exibir uma caixa de entrada para o nome do diretório.
 * 7) Filtra os arquivos terminados com .jpg, .png, e assim por diante (selecionável pelo usuário)
 * 8) Nota: no momento não é possível a seleção de extensões em caixa alta
 * 9) Cria um novo documento
 * 10) Alguma das coisas a serem solucionadas: necessita de um fechamento mais elegante;
 * 11) por enquanto pede que você clique
 * 12) no X no canto superior direito do quadro raiz, mas pelo menos diz quando
 * 13) você deve.
 * 14) Eventualmente ser hábil a navegar entre diretórios, talvez mostrar uma
 * 15) Listbox (lista de seleção) para a seleção do diretório.
 * 1) Eventualmente ser hábil a navegar entre diretórios, talvez mostrar uma
 * 2) Listbox (lista de seleção) para a seleção do diretório.

from scribus import * import Tkinter import os

class ImageDialog(Tkinter.Toplevel): def __init__(self, parent): global jpg, tif, png, pdf, svg, gif Tkinter.Toplevel.__init__(self, parent, bg="#bbbbff")

Tkinter.Label(self, text='Enter the Image Directory, Click OK',bg="#bbbbff").grid(row=0,columnspan=6)

self.e = Tkinter.Entry(self) self.e.grid(row=1,columnspan=6) self.jpg = Tkinter.StringVar self.tif = Tkinter.StringVar self.png = Tkinter.StringVar self.pdf = Tkinter.StringVar self.svg = Tkinter.StringVar self.gif = Tkinter.StringVar b = Tkinter.Button(self, text='OK', bg="#55ff88", command=self.ok) b.grid(row=2,columnspan=6) self.protocol("WM_DELETE_WINDOW", self.quit) Tkinter.Label(self, text='Filters',bg="#bbbbff").grid(row=3) j = Tkinter.Checkbutton(self, text = '.jpg', variable = self.jpg,onvalue='.jpg') j.grid(row=4,column=0) t = Tkinter.Checkbutton(self, text = '.tif', variable = self.tif,onvalue='.tif') t.grid(row=4,column=2) p = Tkinter.Checkbutton(self, text = '.png', variable = self.png,onvalue='.png') p.grid(row=4, column=4) P = Tkinter.Checkbutton(self, text = '.pdf', variable = self.pdf,onvalue='.pdf') P.grid(row=5, column=0) s = Tkinter.Checkbutton(self, text = '.svg', variable = self.svg,onvalue='.svg') s.grid(row=5, column=2) g = Tkinter.Checkbutton(self, text = '.gif', variable = self.gif,onvalue='.gif') g.grid(row=5, column=4) j.select # uncomment these to have default on settings in Checkbuttons
 * 1)        t.select # j = .jpg, t = .tif, etc.
 * 2)        s.select
 * 3)        p.select
 * 4)        P.select
 * 5)        g.select

def ok(self): m = Tkinter.Message(root, text="Agora clique no X no canto superior direito desta janela") m.grid(row=0, columnspan=4) try: D=[] imagecount = 0 filetype = [] if len(self.jpg.get) == 4: filetype.append(self.jpg.get) if len(self.tif.get) == 4: filetype.append(self.tif.get) if len(self.png.get) == 4: filetype.append(self.png.get) if len(self.pdf.get) == 4: filetype.append(self.pdf.get) if len(self.svg.get) == 4: filetype.append(self.svg.get) if len(self.gif.get) == 4: filetype.append(self.gif.get) d = os.listdir(self.e.get) for file in d:               for format in filetype: if file.endswith(format): D.append(file) D.sort xpos = (25, 321) ypos = (42, 236, 430, 624) pwidth = 250 pheight = 187
 * 1) Há 8 imagens por página; xpos e ypos são as coordenadas  x,y do canto superior esquerdo
 * 1) Esta proporção é a certa para fotografias (pelo menos com a minha digital Olympus)

if newDoc(PAPER_A4, (10,10,20,20),PORTRAIT, 1, UNIT_POINTS, NOFACINGPAGES, FIRSTPAGERIGHT): while D[imagecount]: if imagecount > 0: newPage(-1) L = createText(15, 20, 200, 20) setText("Dir: " + self.e.get, L)                   setTextAlignment(ALIGN_LEFT, L)                    setFont("Luxi Sans Regular", L)                    setFontSize(10, L)                    for yframe in ypos: for xframe in xpos: if D[imagecount]: f = createImage(xframe, yframe, pwidth, pheight) loadImage(self.e.get + '/' + D[imagecount], f)                               setScaleImageToFrame(scaletoframe=1, proportional=1, name=f) lenfilename = len(D[imagecount]) Lpiclen = int(5.3 * lenfilename) Lpic = createText(xframe + (250 - Lpiclen), yframe + 172, Lpiclen, 15) setText(D[imagecount], Lpic) setTextAlignment(ALIGN_RIGHT, Lpic) setFont("Luxi Mono Regular", Lpic) setFontSize(8, Lpic) setFillColor("White", Lpic) imagecount = imagecount + 1 setRedraw(1) redrawAll self.Tkinter.Toplevel.destroy except os.error, value: Tkinter.Button(root, text=value[1], bg="#ffff55").grid(row=3, columnspan = 4)
 * 1) L é o quadro no topo de cada página que mostra o nome de diretório
 * 1) Aqui é onde nós estamos carregando as imagens na página, oito por vez, então volta e cria uma nova página
 * 1) Lpic é o título de cada imagem com as posição e largura ajustadas
 * 2) de acordo com a largura do texto.
 * 3) Então se você mudar a fonte ou o seu tamanho, talvez você precise ajustar
 * 4) isto para um calculo aproximado.

root = Tkinter.Tk root.update

d = ImageDialog(root)

root.wait_window(d)