Django ImageField 与 JPEG 的问题
我在 Django 中的 PIL(Python 图像库)方面遇到了一个重大问题,并且已经跳过了很多麻烦,到目前为止还无法弄清楚问题的根源是什么。
问题本质上归结为无法通过 Django 管理中的 ImageField 上传 JPEG 图像。但问题并不像安装libjpeg那么简单。
首先,我安装了 PIL(通过 Buildout),并在安装后意识到我没有安装 libjpeg,因为 JPEG 支持不可用。
由于没有自己设置服务器,我只是假设它没有安装,然后我从源代码编译了 libjpeg 8。这最终出现在我的 /usr/local/lib/ 目录中。我清除了 Buildout 文件并重建了所有内容。这次编译 PIL 时我有了 JPEG 支持。但我去了 Django Admin 并尝试通过 ImageField 上传 JPEG,但没有成功。我收到“上传有效图像。您上传的文件不是图像或图像已损坏”错误。作为测试,我打开了 Djano shell 并运行了以下命令:
> import Image
> i = Image.open( "/absolute_path/file.jpg" )
> print i
<JpegImagePlugin.JpegImageFile image mode=RGB size=940x375 at 0x7F908C529BD8>
运行时没有错误,并表明 PIL 能够打开 JPEG。
读了一些书后,我发现了这个线程: 是否可以控制 apache 使用哪些库?
看起来 PHP 也使用 libjpeg 并且在 Django 之前加载,因此在 Django 之前加载 libjpeg 6.2。这是使用 lsof 时显示的:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 2561 www-data mem REG 202,1 146032 639276 /usr/lib/libjpeg.so.62.0.0
所以我的想法是我应该使用 libjpeg 6.2。所以我删除了位于 /usr/local/lib 目录中的 libjpeg。重新阅读 PIL 安装说明后,我意识到我可能没有 PIL 所需的 libjpeg 的 dev/头文件。因此,我还使用 aptitude 卸载程序卸载了 libjpeg (sudo aptitude remove libjpeg62)。然后,为了确保获得 PIL 所需的头文件,我使用 aptitude 安装了 libjpeg:(sudo aptget install libjpeg62-dev)。
从这里我清理了 Buildout 目录,并重新运行 Buildout,这又重新安装了 PIL。我再次获得了 JPEG 支持,现在使用 libjpeg62。
所以我去Django Admin中进行测试。仍然不支持 JPEG。所以我想测试一般的 JPEG 支持,看看异常是否没有被处理,它会抛出什么样的错误。因此,在我的主页视图中,我添加了以下代码来打开 JPEG 图像:
import Image
i = Image.open( "/absolute_path/file.jpg" )
v = i.verify()
然后我将 i 传递到 HTML 视图,以便轻松查看输出。我将这些更改部署到服务器并重新启动。我很惊讶没有看到错误并得到以下输出:
{{ i }} - <JpegImagePlugin.JpegImageFile image mode=RGB size=940x375 at 0x7F908C529BD8>
{{ v }} - None
所以此时我真的很困惑:
- 为什么我可以成功打开 JPEG 而管理员却不能?
- 我错过了什么吗,这不是 libjpeg 的问题吗?
- 如果 libjpeg 不是问题,为什么我可以毫无问题地上传 PNG?
任何帮助将不胜感激,我已经对此进行了 2 天的调试,但没有运气。
设置: 1.Rackspace云服务器 2.Ubuntu 10.04 3. Django 1.2.3(通过 Buildout 安装) 4. PIL 1.1.7(通过构建安装) 5. libjpeg 6.2(通过 aptitude 安装(sudo aptget install libjpeg62-dev)
I am having a major issue with PIL (Python Image Library) in Django and have jumpped through a lot of hoops and have thus far not been able to figure out what the root of the issue is.
The problem essentially breaks down to not being able to upload JPEG images through the ImageField in the Django admin. But the issue is not as simple as installing libjpeg.
First, I installed PIL (through Buildout) and realized once it was installed that I had not installed libjpeg because JPEG support was not available.
Having not setup the server myself, I just assumed that it was not installed and I compiled libjpeg 8 from the source. This ended up in my /usr/local/lib/ directory. I cleared out my Buildout files and rebuilt everything. This time when PIL compiled I had JPEG support. But I went to the Django Admin and tried to upload a JPEG though an ImageField with no luck. I got the "Upload a valid image. The file you uploaded was either not an image or a corrupted image" error. Just as a test I opened up a the Djano shell and ran the following:
> import Image
> i = Image.open( "/absolute_path/file.jpg" )
> print i
<JpegImagePlugin.JpegImageFile image mode=RGB size=940x375 at 0x7F908C529BD8>
This runs with no errors and shows that PIL is able to open JPEG's.
After doing some reading, I come across this thread:
Is it possible to control which libraries apache uses?
Looks like PHP also uses libjpeg and is loading before Django, and therefor loading libjpeg 6.2 before. This is show when using lsof:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 2561 www-data mem REG 202,1 146032 639276 /usr/lib/libjpeg.so.62.0.0
So my thought is that I should be using libjpeg 6.2. So I removed libjpeg located in my /usr/local/lib directory. After rereading the PIL installation instructions, I realized that I might not have the dev/header files for libjpeg that PIL needs. So I also uninstalled libjpeg using the aptitude uninstaller (sudo aptitude remove libjpeg62). Then to ensure that I got the header files that PIL needed I installed libjpeg using aptitude: (sudo aptget install libjpeg62-dev).
From here I cleaned out my Buildout directory, and reran Buildout, which in turn reinstalled PIL. Once again, I have JPEG support, now using the libjpeg62.
So I go to test in the Django Admin. Still no JPEG support. So I wanted to test JPEG support in general and see if the exception was not handled, what kind of error it would throw. So in my homepage view I added the following code to open a JPEG image:
import Image
i = Image.open( "/absolute_path/file.jpg" )
v = i.verify()
Then I pass i to the HTML view just to easily see the output. I deploy these changes to the server and restart. I am surprised not to see an error and get the following output:
{{ i }} - <JpegImagePlugin.JpegImageFile image mode=RGB size=940x375 at 0x7F908C529BD8>
{{ v }} - None
So at this point I am really confused:
- Why can I successfully open a JPEG while the admin cannot?
- Am I missing something, is this not an issue with libjpeg?
- If not an issue with libjpeg, why can I upload a PNG with no issues?
Any help would be much appreciated, I have been on this for 2 days debugging with no luck.
Setup:
1. Rackspace Cloud Server
2. Ubuntu 10.04
3. Django 1.2.3 (Installed though Buildout)
4. PIL 1.1.7 (Installed though Buildout)
5. libjpeg 6.2 (installed through aptitude (sudo aptget install libjpeg62-dev)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你想想看,我会在发帖后 5 分钟内解决这个问题。我不确定真正的问题最终是什么,但这就是我解决它的方法。
自从使用 aptitude 安装 libjpeg 以来,我考虑使用 Aptitude 而不是 Buildout 安装 PIL。
我最终做的是:
然后我从 Buildout 中删除了 PIL,重新构建了我的项目并且它起作用了。现在 PIL 和 libjpeg 是通过 Aptitude 安装的,这似乎解决了 PIL 查找 libjpeg 的任何问题。
Go figure, that I would solve this 5 minutes after posting. I am not sure what the true issue ended up being, but that is how I solved it.
Since installing libjpeg with aptitude, I looked into installing PIL with Aptitude rather than Buildout.
What I ended up doing was:
Then I removed PIL from my Buildout, re-built my project and it worked. Now that PIL and libjpeg were installed through Aptitude it appears as though this resolved any issue PIL had finding libjpeg.