pyvips icon indicating copy to clipboard operation
pyvips copied to clipboard

Image.new_from_file() Only accept path folder?

Open vncsms opened this issue 6 years ago • 4 comments

In my code i have this follow code:

    def make_thumbs(self, obj, file, *args):
        img = PilImage.open(file)

        originalThumbStr = StringIO.StringIO()
        img.convert('RGBA').save(originalThumbStr, 'webp', quality=75)
        self.img_file = InMemoryUploadedFile(originalThumbStr, None,
                                             hash_str('image') + '.webp',
                                             'image/webp',
                                             originalThumbStr.len, None)

In resume this code receive a file of type: <class 'django.db.models.fields.files.ImageFieldFile'> and i convert to differents sizes and save in DB. Now i want use the pyvips, because is more fast to convert images to WEBP, but i'm not sure how to use, because i don't know how load a image that not come from a folder. So i do the follow attempt:

    def make_thumbs(self, obj, file, *args):

        originalThumbStr = StringIO.StringIO()
        img = pyvips.Image.new_from_file(file, access='sequential')
        img.write_to_file(originalThumbStr)
        self.img_file = InMemoryUploadedFile(originalThumbStr, None,
                                             hash_str('image') + '.webp',
                                             'image/webp',
                                             originalThumbStr.len, None)

I know some errors will appear, but i don't know if pyvips can load a image the same way PIllow does: img = PilImage.open(file) and save with StringIO. Is there a way the pyvips can do this?

Internal Server Error: /api/v1/image/upload
Traceback (most recent call last):
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/rest_framework/views.py", line 452, in dispatch
    response = self.handle_exception(exc)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/rest_framework/views.py", line 449, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/rest_framework/generics.py", line 244, in post
    return self.create(request, *args, **kwargs)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/rest_framework/mixins.py", line 20, in create
    self.perform_create(serializer)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/rest_framework/mixins.py", line 25, in perform_create
    serializer.save()
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 165, in save
    self.instance = self.create(validated_data)
  File "/home/developer/projects/prisvo/prisvo-backend/image/serializers.py", line 48, in create
    ret = super(ImageCreateSerializer, self).create(validated_data)
  File "/home/developer/projects/prisvo/prisvo-backend/common/serializers.py", line 14, in create
    return self.Meta.model.objects.create(**validated_data)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/django/db/models/query.py", line 372, in create
    obj.save(force_insert=True, using=self.db)
  File "/home/developer/projects/prisvo/prisvo-backend/image/models.py", line 78, in save
    self.make_thumbs(self, original_img)
  File "/home/developer/projects/prisvo/prisvo-backend/image/models.py", line 47, in make_thumbs
    img = pyvips.Image.new_from_file(file, access='sequential')
  File "/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/pyvips/vimage.py", line 209, in new_from_file
    pointer = vips_lib.vips_filename_get_filename(vips_filename)
TypeError: initializer for ctype 'char *' must be a cdata pointer, not ImageFieldFile
[06/Feb/2019 10:38:51] "POST /api/v1/image/upload HTTP/1.1" 500 152340

vncsms avatar Feb 06 '19 16:02 vncsms

Hello @vncsms,

You need new_from_buffer and write_to_buffer:

#!/usr/bin/python3

import sys
import pyvips
  
buf = open(sys.argv[1], "rb").read()

im = pyvips.Image.new_from_buffer(buf, "", access="sequential")
buf_out = im.write_to_buffer(".webp")

open(sys.argv[2], "wb").write(buf_out)

You can run like this:

$ ./to_webp.py ~/pics/k2.jpg x.webp

To convert jpg->webp.

To make thumbnails, use thumbnail_buffer instead, eg.

#!/usr/bin/python3

import sys
import pyvips
  
buf = open(sys.argv[1], "rb").read()

im = pyvips.Image.thumbnail_buffer(buf, 128)
buf_out = im.write_to_buffer(".webp")

open(sys.argv[2], "wb").write(buf_out)

To make a 128 x 128 pixel webp thumbnail.

jcupitt avatar Feb 06 '19 17:02 jcupitt

OK. I tried again:

def make_thumbs(self, obj, file, *args):
    img = PilImage.open(file)
    img.save(originalThumbStr, 'png')
    img = pyvips.Image.new_from_buffer(originalThumbStr.getvalue(), '', acess="sequencial")

But the third line give the error:

*** TypeError: initializer for ctype 'int(*)(void *, void *)' must be a pointer to same type, not cdata 'void(*)(void *)

So, i tried the basic:

    import sys
    import pyvips
  
    buf = open('222.jpg', "rb").read()
    im = pyvips.Image.new_from_buffer(buf, "", access="sequential")

And a wild error appears:

TypeError: initializer for ctype 'int(*)(void *, void *)' must be a pointer to same type, not cdata 'void(*)(void *)'

The new_file_buffer can help my problem, but now i cant solve this error.

The 222.jpg image:

222

vncsms avatar Feb 07 '19 16:02 vncsms

Sorry, no idea, I guess there must be something funny about your install.

I'll make you a tiny Dockerfile.

jcupitt avatar Feb 07 '19 17:02 jcupitt

Try this:

https://github.com/jcupitt/docker-builds/tree/master/pyvips-python3

I see:

$ docker pull python:3
3: Pulling from library/python
...
Status: Downloaded newer image for python:3
$ docker build -t pyvips-python3 .
Sending build context to Docker daemon  875.5kB
Step 1/4 : FROM python:3
 ---> 338b34a7555c
...
Successfully built 935e73c85f85
Successfully tagged pyvips-python3:latest

Then I can run it with:

$ docker run --rm -it -v $PWD:/data pyvips-python3
Python 3.7.2 (default, Feb  6 2019, 12:04:03) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyvips
>>> x = pyvips.Image.new_from_file("/data/222.jpg", access="sequential")
>>> x.width
1920
>>> 

That's debian stretch with a pre-built py3 install, then libvips added via apt. What platform are you using?

jcupitt avatar Feb 07 '19 17:02 jcupitt