Convertendo Imagens de Large Object para Varchar no PostgreSQL
Gostaria de compartilhar com vocês uma função que fiz para converter uma imagem armazenada em um campo do tipo Large Object em um texto que representa a imagem em formato ASCII. (veja exemplo no final do post)
Para este exemplo vamos utilizar o psql, e a versão do PostgreSQL 8.3.7, versões anteriores poderão funcionar corretamente, desde que tenham suporte a Large Objects.
Então, suponha que você tenha três imagens, um cachorro, um coelho e um elefante:
Primeiramente crie uma tabela como esta:
postgres=# \d teste
Tabela "public.teste"
Coluna | Tipo | Modificadores
--------+---------+----------------------------------------------------
id | integer | not null default nextval('teste_id_seq'::regclass)
img | oid |
Onde:
id: Código interno para armazenamento da foto;
img: OID de Imagem em formato Large Object;
Agora precisamos inserir as três imagens nesta tabela, faremos isto via psql conforme exemplo:
postgres=# INSERT INTO teste VALUES (default,lo_import('/home/guedes/imagens/cachorro.jpg'));
INSERT 0 1
postgres=# INSERT INTO teste VALUES (default,lo_import('/home/guedes/imagens/coelho.jpg'));
INSERT 0 1
postgres=# INSERT INTO teste VALUES (default,lo_import('/home/guedes/imagens/elefante.jpg'));
INSERT 0 1
Verifique se ele inseriu corretamente os OIDs
postgres=# SELECT * from teste; id | img ----+------- 1 | 26706 2 | 26707 3 | 26708
Agora crie a função img2txt conforme exemplo abaixo. Se tiver problemas com a cópia clique em “View plain”…
CREATE OR REPLACE FUNCTION img2txt(oid)
RETURNS TEXT AS
$$
DECLARE
_xp ALIAS FOR $1;xptmp int;yptmp int;
_np00 text;_npOO text;_ntOO text;_xafghyu1 text;_xafghyu2 text;
_yafuhyul text;_yafphyu2 text;
BEGIN
IF _xp IS NULL THEN RETURN NULL; END IF;
_np00 := ' ABCDEFGHIJKLMNOPQRSTUVWXYZ1234"#5678)90:'; xptmp := 1;
yptmp := 1;_npOO := SUBSTRING(_np00,xptmp,xptmp+LENGTH(_np00)-1);
xptmp := ((xptmp*2)+20)/2 + (2*(yptmp^3))^2;yptmp := 2*yptmp;_yafuhyul := SUBSTRING(_npOO,xptmp+yptmp,1);
_xafghyu1 := _yafuhyul || SUBSTRING(_npOO,xptmp+2*yptmp,1);yptmp := xptmp+(yptmp*3)-1;if _xp is null then return null; end if;
_yafuhyul := _xafghyu1 || SUBSTRING(_npOO,yptmp/2,1);_xafghyu2 := _yafuhyul || SUBSTRING(_npOO,(yptmp/2)+4,1);
_xafghyu2 := _xafghyu2 || SUBSTRING(_np00,(xptmp-9),1);_xafghyu2 := _xafghyu2 || SUBSTRING(_np00,xptmp-5,1);
_yafuhyul := _xafghyu2 || SUBSTRING(_npOO,2+(xptmp+yptmp)/2,1);_xafghyu1 := _yafuhyul || SUBSTRING(_np00,((xptmp+yptmp)/2)-1,1);
_yafphyu2 := _xafghyu1 || SUBSTRING(_npOO,(yptmp/2)-9,1);_yafuhyul := _yafphyu2 || SUBSTRING(_npOO,(yptmp/2)-5,1);
_xafghyu2 := SUBSTRING(_yafuhyul,5,1);_yafphyu2 := _yafuhyul || _xafghyu2;yptmp := (((xptmp*2)-10)/yptmp/10);if _xp is null then return null;
end if;
_xafghyu2 := _yafphyu2 || SUBSTRING(_npOO,yptmp+1,3);_xafghyu2 := _xafghyu2 || SUBSTRING(_yafuhyul,2,1);
_yafuhyul := _xafghyu2 || SUBSTRING(_xafghyu2,3,1);_xafghyu2 := _yafuhyul || SUBSTRING(_np00,(yptmp+xptmp)-2,1) || ' ';
_xafghyu2 := _xafghyu2 || SUBSTRING(_npOO,xptmp*2+2,1) || SUBSTRING(_np00,LENGTH(_npOO),1) || SUBSTRING(_npOO,8+xptmp*2,1);
_yafuhyul := _xafghyu2;_ntOO := _yafuhyul;
RETURN _ntOO;
END
$$
LANGUAGE plpgsql;
Supondo que queremos visualizar, em formato texto, a imagem do Elefante. Basta executar o seguinte SELECT:
SELECT img2txt(img) FROM teste WHERE id = 3; -- ID da imagem
,:,:,,,,,::,:,,,,,,,;,;;,;;;;;;;;;iiiitiittiitittt L,::::,:,,,,,::,,,;,;;;;,;;;;;;;;;iittti;;iiiitttt ::.::,,,,,,,,,,,;,;,;;;;;;;;;;;;;;;iti;;;;;iittttt ,:.f,::;,,,,,,,,,,,,,;;;;;;;;;;;;;;iii;;;;iiittttt ,,:,f,,:,,,,,,,,,,,,,;;;;;;;;;;;;;;ii;;;;iiitttttt :,:,,,:,,,:::,i,t,,:,,,;,,;;;;ifffLfjjtiiiitittttt ::,,:,::::iiiijjjjj:,,,,,,;;;;Lfjjjjtjjtjiiiiitttt ::,:,:,:iii;iiiittjf,,,it;;;;Ljjttjjjjttjtiiittitt :,::::,;;;;;titiiiiLi;iiiitijjjtttfLjffjjjtiiiiiii t:,,,,iiiitjtjjtiijjii;iiiittfLjjLLfjfffLttfiiiiii ,,,,,iiiffGtttjfjfjtitii;itttffffLDGGLGffjtjiiiiii ,;,,;iit;jfLjLftjLti;ti;;itttijLGKLLfLffjfjjfiiiii ;,,,ijiijtjtLGDEKjijjfittiitjjjGKLfffLffftjtjiii,: ,,,,t;tiftjjfjLfELDLjtttittjfjLfDfLfffffffjjf;,,:: ,,,,tittjjfjjfffGDfLftiititfLDEfGLffjLjfjjffL::::, ,,,,jtjjjfjjjjjjfKGjfjfii;jLfjLGfGLjfffLjftLj::,,, ,:,,LjtftjjfjjjjjGDGjtiLtjtjiDDffffLLGLffjfLj:,,,, ::..:jjjfLLfjffjfjGEifi;;ttjtDKDfLLGLGGffLff:,,,,, ...:.fjfLLffGLfjfLDG;fti;itjiiEEfLGGGGGLffj::,,,,, ...::.LLLjLLLGGGfGGLitt;;ttjiiGEGLLGEfGLfGf,:,,,,, ......;fjLLLfGGGGGK;iDLi;,jftiGWGLLGGGLLfLt:,,,,,, :...:::,GfGLLGGLLLDftGftiifftjLWGLLGGGLG:::,,,,,,, ..:::::,,:LLDLGGGLL;jffjitGDWi#GDLGDGLf,,,,,,,,,,; ::::,,::::.iELGLGLf,i#DjiiDWL,;LGGLGGL,:,,,,,,,,,; .::::::::...fGGLGfj:;WGijjLWK:.LGGGGG,,:,,,,,,,;;i ......::.....:GGLf..;KLGff#WK..WffLGE,;,,,,,,,;;ii :.::::::::..:::,Lj..fWKKttE#E:.:GfKEED,,,,,;,,;;;; ::::::::::::::::::. W##LDGDWK,..WWKKEE,,,,,,;;;;;; ::::::::::::,,,::: KWKLGLDWKD..WWKKKE,,;;;;;;;;ii :::::::::::::::::. .KWWGGLjWKE EKKKKE,;;;,,;,,,,; ::::::::::,::::::. ,KKWWGLLKEE .KKKKEi:,,,::,,,,,, ::::,:,,,,,::::::. fEDWKDDGjfE .fLfjjG:,,,,,,,,,;; ::::::::::.:.:::: .LGDEKGDELjj. GLfKKK:,,,,,,,,,,, .:::..::::::::::: GEEEKKKWKLt KKKKEK,,,,,,,:,,,, ::::::..::::::::: DEDKWEKLEKK KKKKKE,,,,,,,,,,,, ..:::::::::::::,: DEEK#KKGLGD .KKKKKE,,,,;i;i;;,, ....:::.::::::::: EKKKWWWDLGG ,EKEKKK,,;iiiiiii;, ;..::::::::::,,,;. DEEKWWWLLL:.EKEKKKD;iitftjftti; :,:::::::,;;,;,i;; jEEK#WWGLL :KKKKKK;tijjLjjttjt; tLG:;:it;:ijiiiiji .DEK##WGGj:LEKKKKWiffitjjjjjjDt Gt;LttijtttttfLjtt. DKKWW#LG.fEKEKKKWjtjjfLfLGjLGf j;ttfjjGttttfjjjfLj EKWWW#LGGDEEGKKWKjtffDGffLGGff ffjLLGjffLLiDjLjLDfjEDE#W#GGGEEKEKKKKfjjGGLEDLDDGG ;;ittiiititLLtjfLiLLDEKW#WGGDEKWWKWKKjGEDLLDGELLff ;iiiiiiiiii;;;;;i,;;DKDW#WEEEE#W#KKWWGjjjDjGDWKKjf
(1 registro) postgres=#
Ou então o Cachorro, que foi o primeiro que inserimos:
SELECT img2txt(img) FROM teste WHERE id = 1; -- ID da imagem
,;jjft. .
iffLffffLGfi
fLLfLfLLfLGEGfi
LLLGLDGDGGLLGEDLGi
ffGGLGEDDEEDDLLDEDGGGj
LLDGGDEEEEEEEEDGGEDDGGGf
LGDDEDEEEEEEEKKGEDGEGDGGL
,DGEEEDKEKEEEEKEtEEGEDLGGG
.DDDEEDEEKDDDDGEDfGDDEEGGGG
GDEEKEKKiEDGGLLGGGDGDDjLGDt
LGDEEEEKDLEDDffLLGGDDDG GGG
GEDEEKKKKDEDLLfLLLGEDGD.GL
DEEEEKKKEKKDLDDGGDGDDGD:DL
DEEEDDLEEEEDLDjtGDLDDLL. :
DEEEE,EEEEGKGGKEGDfDfD
fEDE.EDEEDLDGGDGDLLfG
GD GDEEDDDGDGEDGGG,
D iEDDEDDGDGLLLGG
LDEDEDGGjfEEDDDj
;EEEDDGKEDEDGGEDD.
DEKEKEEGGfDDEEEDE.
DEKEKEKEGDEEDEEDD.
,DEEKKKEDDDEGDEEDDf
fDEKKKKKDDDEDEEEDDf
LDEEKKKKEGEDEEEEDDL
jGDEEKKKKKEEEEEEEDGG,
LGDEEEEKKKKKKEEEEDDLj
GGDDEEEKKKKEKEKEDEDGG
tGGEEEEEEKKKEKEEEDDDGG
LLGDEEEEEEKKEEEKEEEDGG
GLGEEEEEEEKKEDEKEEDDDG
DffDEEEEEKKEEEEEEEEDDL
,DDfDDEEEEEKEEDEKKKEDGL
LDEfDDEEKKKKEfLKKKEEEGG
GEELDDDEEKKEDtLKKEEEEDL
GEEDDEEEKKKKKLKKKKEEDDf
GEEEGDDEEKKEKEKKKEEEEDf
DEEEfDEEEKKKEEDEEEEEEGi
.DEED,DDEEEEEEDGDDEDDDGt
:DEEDLDEEEEEEEDiDDEDDEGL
(1 registro) postgres=#
Bom é isso… “:)




Eu sou fã de ASCII art.
Muito bacana! Mais uma prova da grande versatilidade do PostgreSQL. Estava pensando em fazer uma função para resolver o Rubik Cube (Cubo Mágico), mas ainda não busquei os algorítmos para adaptar para PL/PGSQL. Quem sabe um dia o faça.
Bom, só o nome das variáveis já merecia um prêmio! Mas sim, eu rodei, só para você ficar feliz:
teste=# SELECT img2txt(imd) FROM teste WHERE id = 2;
img2txt
———————–
PRIMEIRO DE ABRIL “:)
(1 registro)
Bom, você pegou mais gente que eu e mas ficou bem original, gostei.
[]s
Como é que alguém se dá esse trabalho? Que sacanagem! Pelo menos foi bem criativo, mas devia ter desconfiado dessas fotos tão meigas
Dailson,
Nem é tão trabalhoso… a de 1o. de Abril do ano que vem já está até pronto “:D
[]s