terça-feira, 10 de julho de 2012

Python - Problemas com a biblioteca PIL

Esses dias houve um problema no servidor e tivemos que reinstalar o python e todos os seus pacotes. E, claro, alguns erros começaram a acontecer. Em especial, problemas com a PIL (Python Imaging Library). Os quais vamos tratar aqui.


Como instalar

Para instalar a PIL, você pode usar ferramentas como o setuptools:

easy_install http://effbot.org/downloads/Imaging-1.1.7.tar.gz
O pacote PIL não funciona muito bem com o easy_install. Por isso, aponte diretamente para o pacote para instalá-lo. "easy_install PIL" costuma não funcionar (ele não encontra o pacote).

Porém, antes de instalar, dê uma lida nos próximos tópicos para evitar surpresas. Acredite, um ou mais dos erros listados aqui tem grandes chances de acontecer.

Erro 1 - Suporte a formatos de imagens

O primeiro erro que ocorreu foi o Django ter parado de suportar imagens jpg. Algo bem estranho pois é um formato extremamente comum e, claro, o cliente não ficou muito contente com o sistema não aceitar a imagem que ele estava tentando enviar. Além dele ter começado a falar que o sistema estava completamente comprometido, que ficou impossível de usar e daí pra frente. Tudo por causa de dois campos de imagem que não estavam funcionando tão bem quanto deveriam. Enfim.

O suporte de imagens da PIL é instalado e configurado conforme as bibliotecas que você tem no seu sistema, ou seja, se no momento da instalação você não tiver as bibliotecas de jpg instaladas, ele sera instalado sem suporte a jpg. Que foi exatamente o que aconteceu.
--------------------------------------------------------------------
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version       1.1.7
platform      linux2 2.7.3 (default, May  9 2012, 20:23:06)
              [GCC 4.4.3]
--------------------------------------------------------------------
*** TKINTER support not available
*** JPEG support not available
--- ZLIB (PNG/ZIP) support available
*** FREETYPE2 support not available
*** LITTLECMS support not available
--------------------------------------------------------------------
Mensagem exibida no término da instalação da PIL mostrando os formatos de imagem que ele encontrou suporte no seu sistema.

Para instalar os pacotes para suporte a jpg basta:
sudo apt-get install libjpeg-dev
sudo apt-get install libfreetype6 libfreetype6-dev

Por garantia, tenha sempre os headers do python instalados:
sudo apt-get install python-dev
Embora isso não seja tão divulgado por aí quanto deveria, muitos pacotes python dependem desse pacote. Sabe aqueles erros malucos na instalação que te deixam numa situação do tipo "WTF?!?!"? Provavelmente é a ausência de algum pacote como esse. Por exemplo, o django-sentry é um pacote que depende desses headers. Demorei mais de uma semana pra encontrar essa solução num site em japonês! Bem, continuemos.

Caso o suporte a imagens não tenha sido instalado, mesmo com os pacotes corretos instalados, você precisa criar alguns links simbólicos e executar a instalação do PIL de novo:
ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib
ln -s /usr/lib/x86_64-linux-gnu/libfreetype.so /usr/lib
ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib

easy_install http://effbot.org/downloads/Imaging-1.1.7.tar.gz

Agora a listagem de suporte a formatos deve mudar. ;)
--------------------------------------------------------------------
*** TKINTER support not available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
*** LITTLECMS support not available
--------------------------------------------------------------------

Erro 2 - No module named 'PIL'

Esse erro é muito chato e creio que o mais comum. Você instala o pacote, tudo corre bem, o suporte aos formatos de imagem de que você precisa está correto. Mas quando você, ou algum pacote que você está usando, tenta importar a biblioteca PIL é lançada a exceção: "No module named 'PIL'". O que não faz muito sentido. Você confere, a biblioteca se encontra instalada em "/usr/local/lib/python2.X/dist-packages/" e lá se encontra o pacote instalado (algo do tipo): "PIL-1.1.7-py2.X-linux-i686.egg".
E agora?

A solução que encontrei, convenhamos que é meio porca, mas resolveu completamente esse problema.
Ao acessar a maioria dos pacotes há um diretório com o nome do pacote e dentro deste diretório temos os arquivos. No caso da PIL, olhe o que havia dentro da pasta no meu caso:
ArgImagePlugin.py        FontFile.pyc             ImageCms.pyc      ImageMode.pyc       _imagingmath.pyc       OleFileIO.pyc         SgiImagePlugin.pyc
ArgImagePlugin.pyc       FpxImagePlugin.py        ImageColor.py     ImageOps.py         _imagingmath.so        PaletteFile.py        SpiderImagePlugin.py
BdfFontFile.py           FpxImagePlugin.pyc       ImageColor.pyc    ImageOps.pyc        _imaging.py            PaletteFile.pyc       SpiderImagePlugin.pyc
BdfFontFile.pyc          GbrImagePlugin.py        ImageDraw2.py     ImagePalette.py     _imaging.pyc           PalmImagePlugin.py    SunImagePlugin.py
BmpImagePlugin.py        GbrImagePlugin.pyc       ImageDraw2.pyc    ImagePalette.pyc    _imaging.so            PalmImagePlugin.pyc   SunImagePlugin.pyc
BmpImagePlugin.pyc       GdImageFile.py           ImageDraw.py      ImagePath.py        ImImagePlugin.py       PcdImagePlugin.py     TarIO.py
BufrStubImagePlugin.py   GdImageFile.pyc          ImageDraw.pyc     ImagePath.pyc       ImImagePlugin.pyc      PcdImagePlugin.pyc    TarIO.pyc
BufrStubImagePlugin.pyc  GifImagePlugin.py        ImageEnhance.py   Image.py            ImtImagePlugin.py      PcfFontFile.py        TgaImagePlugin.py
ContainerIO.py           GifImagePlugin.pyc       ImageEnhance.pyc  Image.pyc           ImtImagePlugin.pyc     PcfFontFile.pyc       TgaImagePlugin.pyc
ContainerIO.pyc          GimpGradientFile.py      ImageFileIO.py    ImageQt.py          __init__.py            PcxImagePlugin.py     TiffImagePlugin.py
CurImagePlugin.py        GimpGradientFile.pyc     ImageFileIO.pyc   ImageQt.pyc         __init__.pyc           PcxImagePlugin.pyc    TiffImagePlugin.pyc
CurImagePlugin.pyc       GimpPaletteFile.py       ImageFile.py      ImageSequence.py    IptcImagePlugin.py     PdfImagePlugin.py     TiffTags.py
DcxImagePlugin.py        GimpPaletteFile.pyc      ImageFile.pyc     ImageSequence.pyc   IptcImagePlugin.pyc    PdfImagePlugin.pyc    TiffTags.pyc
DcxImagePlugin.pyc       GribStubImagePlugin.py   ImageFilter.py    ImageShow.py        JpegImagePlugin.py     PixarImagePlugin.py   WalImageFile.py
EGG-INFO                 GribStubImagePlugin.pyc  ImageFilter.pyc   ImageShow.pyc       JpegImagePlugin.pyc    PixarImagePlugin.pyc  WalImageFile.pyc
EpsImagePlugin.py        Hdf5StubImagePlugin.py   ImageFont.py      ImageStat.py        McIdasImagePlugin.py   PngImagePlugin.py     WmfImagePlugin.py
EpsImagePlugin.pyc       Hdf5StubImagePlugin.pyc  ImageFont.pyc     ImageStat.pyc       McIdasImagePlugin.pyc  PngImagePlugin.pyc    WmfImagePlugin.pyc
ExifTags.py              IcnsImagePlugin.py       ImageGL.py        ImageTk.py          MicImagePlugin.py      PpmImagePlugin.py     XbmImagePlugin.py
ExifTags.pyc             IcnsImagePlugin.pyc      ImageGL.pyc       ImageTk.pyc         MicImagePlugin.pyc     PpmImagePlugin.pyc    XbmImagePlugin.pyc
FitsStubImagePlugin.py   IcoImagePlugin.py        ImageGrab.py      ImageTransform.py   MpegImagePlugin.py     PsdImagePlugin.py     XpmImagePlugin.py
FitsStubImagePlugin.pyc  IcoImagePlugin.pyc       ImageGrab.pyc     ImageTransform.pyc  MpegImagePlugin.pyc    PsdImagePlugin.pyc    XpmImagePlugin.pyc
FliImagePlugin.py        ImageChops.py            ImageMath.py      ImageWin.py         MspImagePlugin.py      PSDraw.py             XVThumbImagePlugin.py
FliImagePlugin.pyc       ImageChops.pyc           ImageMath.pyc     ImageWin.pyc        MspImagePlugin.pyc     PSDraw.pyc            XVThumbImagePlugin.pyc
FontFile.py              ImageCms.py              ImageMode.py      _imagingmath.py     OleFileIO.py           SgiImagePlugin.py

Cadê o módulo PIL aí? Não está aí! Nem o diretório com esse nome (que também é tratado como módulo). A solução minha foi criar aí dentro um diretório de nome "PIL" e copiar todos esses arquivos para dentro dele. Tudo passou a funcionar perfeitamente depois disso. ;)

Uma solução alternativa é utilizar o pacote Pillow. Ele é um fork do PIL criado justamente para corrigir problemas como este. Para instalá-lo, basta fazer o seguinte:
sudo easy_install Pillow

Espero que isto ajude a resolver seus problemas. ;)


Fontes:
http://stackoverflow.com/questions/2485295/the-problem-with-installing-pil-using-virtualenv-or-buildouthttp://stackoverflow.com/questions/5085229/python-package-installed-with-easy-install-is-not-being-detected-pil-1-1-7http://stackoverflow.com/questions/8863917/importerror-no-module-named-pilhttp://stackoverflow.com/questions/1815080/easy-install-pil-failshttp://www.martin-geber.com/thought/2007/08/22/problems-installing-easy_install-pil/ e http://stackoverflow.com/questions/6579995/django-no-module-named-pil .




Nenhum comentário: