GithubHelp home page GithubHelp logo

plone / plone.scale Goto Github PK

View Code? Open in Web Editor NEW
2.0 157.0 15.0 2.48 MB

Contains image scaling logic for use in Zope environments. It supports Zope 2, Pyramid and other systems build on using the Zope ToolKit (ZTK).

Home Page: https://pypi.org/project/plone.scale

Python 100.00%

plone.scale's Issues

Solve Problem on waking up the object to get the scales

Problem:

In order to get a scale or generate its tag one must wake up the context object which has the image. In listings this leads to a vast amount of getObject calls.

How it works now

plone.scale created the scale and stores it as an annotation of the object.

Proposed Solution

Rough sketch:

  • Additional store a mapping (content UID, image hash) as an OOBTree as an annotation at portal level on scale creation.
  • Remove the mapping on cleanup
  • Provide an utility to lookup scales UIDs
  • Also (not in here), provide convinicence API for same features - i.e. tag creation - ass @@images does now directly on the object. Idea: As images adapter between catalog brain and request providing the same interface as @@images.

Are image scales thrown away needlessly?

I have heard community members complain about image scales being purged from the storage when there is no reason. I am doing some tests, also adding unit tests, and so far it seems to go how I expect:

  • Add a portal_type with an image field to Plone and view two scales, let's say on @@images/image/mini and @@images/image/preview.
  • Edit the image and only change the title.
  • View the scales: you get the cached scales.
  • Edit the image and upload a different image.
  • View the mini scale: the old mini scale is explicitly removed and a new one is generated. The preview scale is kept.
  • View the preview scale 24 hours later via the unique url: you get the cached scale, even though it is outdated.
  • View the large scale: you have not viewed this yet, so a new scale is generated. This triggers cleaning up outdated scales.
  • The cached preview scale is removed because it is older than 24 hours and is outdated.
  • The cached mini scale is kept even though it is older than 24 hours: it is not outdated.

So that seems fine.

The only other thing I fear could be true, is:

  • You have a portal_type with two image fields.
  • Upload to image field 1, save, generate a scale.
  • Upload to image field 2, maybe after 24 hours, save, generate a scale.
  • This might throw away scales from image field 1, although they are not outdated.

Is that maybe the case?

@datakurre I think at least you reported this.

Scales and read-only frontend

We have a Plone setup with two frontends. One for editors which uses read-write plone instances and one for publicity with read-only plone instances, this looks like this:

      ┌─────────────────┐                 ┌──────────────────┐
      │ www.oursite.com │                 │ cms.oursite.com  │
      │ for publicity   │                 │ for editors      │
      └───────┬─────────┘                 └────────┬─────────┘
              │                                    │
              │                                    │
              ▼                                    ▼
 ┌────────────────────────────┐        ┌───────────────────────────┐
 │ read-only plone instances  │        │read-write plone instances │
 └─────────────┬──────────────┘        └───────────┬───────────────┘
               │                                   │
               │                                   │
               │                                   │
               │            ┌───────────┐          │
               └─────────►  │           │ ◄────────┘
                            │    ZEO    │
                            │           │
                            │           │
                            └───────────┘

cms.oursite.com is only accessible from our intranet - so we have some extra security here.

If an image scale is not accessed via cms.oursite.com before it is accessed via www.oursite.com we will get an "ReadOnlyError" because scaling happens on demand.

We have tried to work around this issue by creating scales on save but it is not very reliable.

Now we consider read-write access from www.oursite.com but maybe there is an other better solution for this?

Scaled image with mode LA is just a black square.

I have a problem when scaling the attached image. This image has mode LA. When I upload this image in Plone, the scaled versions are all black squares. When I convert the image to mode P and upload that image, the scaled versions are correct. Also, when I do the scaling on the command line, following the same steps, the scaled versions are also correct. Is this a problem with plone.scale or PIL or the image itself?

boek-la

Implementing an IImageScaleStorage that stores scales only in memory

I have an application where image scales are heavily used, and once they are generated they are stored forever, even when they are not useful anymore.

So I'm thinking about implementing a new IImageScaleStorage implementation, where scales are stored only in RAM memory. If memory was infinite it would be easy. However I would like to store the scales in a cache, where least used scales would get purged eventually (probably Zope's RAM cache, but that's just an implementation detail). The problem is when a client of the storage requests an image by it's UID and it is not in the cache anymore. Example: when a user requests the scale by its UID based URL.

To solve this the storage itself could re-generate the scale, but it doesn't know what are the scaling parameters (width, height etc). Unless the parameters are contained in the UID!

In the README I found this statement:

image scaling parameters should not be part of the generated URL. Since the number of parameters can change and new parameters may be added in the future this would create overly complex URLs and URL parsing.

However I thought of an easy way to solve the problems mentioned in the statement. I could encode the parameters as JSON and apply base64 encoding. For example:

>>> parameters = '{width:100,height:100,direction:'down',quality:88}'
>>> uid = base64(parameters)  
e3dpZHRoOjEwMCxoZWlnaHQ6MTAwLGRpcmVjdGlvbjonZG93bicscXVhbGl0eTo4OH0K
>>> len(uid)
68

URL would be not that big (67 chars in the example), parsing and encoding are straightforward and it is futureproof regarding inclusion of new parameters.

So what do you think? Do you see any caveats I am missing? Do you think such a scale storage would be generally useful and worth inclusion in this package? I could open a PR for that.

PS.: This is actually not an issue nor a question, it is a request for thoughts about this idea. I thought about posting it on the Plone Community forum but I think here I have more chances of reaching people how knows more about scaling specifics. I hope this is OK.

Stop testing master branch with Plone 5.2

The master branch of plone.scale is only used for Plone 6. We should stop testing with the version pins from Plone 5.2 and declare that we've removed support for it.

Delete scale sometimes fails because values and items are out of sync

Plone 4.3.11, plone.scale 1.4.1, RelStorage.
This is an old copy of the site on a development server, where I just updated from Plone 4.3.6 to 4.3.11. And added five.pt, though I don't think that matters here. The homepage showed fine before, but now fails:

Traceback (innermost last):
  Module ZPublisher.Publish, line 138, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 48, in call_object
  Module Products.minaraad.browser.homepage, line 20, in __call__
  Module Products.Five.browser.pagetemplatefile, line 125, in __call__
  Module Products.Five.browser.pagetemplatefile, line 59, in __call__
  Module zope.pagetemplate.pagetemplate, line 132, in pt_render
  Module five.pt.engine, line 98, in __call__
  Module z3c.pt.pagetemplate, line 163, in render
  Module chameleon.zpt.template, line 261, in render
  Module chameleon.template, line 191, in render
  Module chameleon.template, line 171, in render
  Module e0d298331ef610c65315d9e5fee21810.py, line 1188, in render
  Module 783a713b2da0eedfb1f625102403febe.py, line 1392, in render_master
  Module 783a713b2da0eedfb1f625102403febe.py, line 559, in render_content
  Module e0d298331ef610c65315d9e5fee21810.py, line 414, in __fill_content_core
  Module plone.app.imaging.scaling, line 185, in scale
  Module plone.app.imaging.scaling, line 272, in getInfo
  Module plone.scale.storage, line 158, in scale
  Module persistent.mapping, line 59, in __delitem__
  Module UserDict, line 25, in __delitem__
KeyError: 'c639a89a-bbc4-41c3-80a0-b68b1f0b5e69'

 - Expression: "python:images.scale('image', width=100, height=100, direction='down')"

It goes wrong on the del line here in storage.py:

    def scale(self, factory=None, **parameters):
        key = self.hash(**parameters)
        storage = self.storage
        info = self.get_info_by_hash(key)
        if info is not None and self._modified_since(info['modified']):
            del storage[info['uid']]

Checking with a pdb, we have this hash key:

(('direction', 'down'), ('fieldname', 'image'), ('height', 100), ('width', 100))

It is in the storage values:

((Pdb)) pp [x['key'] for x in self.storage.values()]
[(('direction', 'down'),
  ('fieldname', 'image'),
  ('height', 105),
  ('width', 105)),
 (('direction', 'down'),
  ('fieldname', 'image'),
  ('height', 105),
  ('width', 105)),
 (('direction', 'down'),
  ('fieldname', 'footerImage'),
  ('height', 500),
  ('width', 1500)),
 (('direction', 'down'),
  ('fieldname', 'footerImage'),
  ('height', 500),
  ('width', 1500)),
 (('direction', 'down'),
  ('fieldname', 'image'),
  ('height', 100),
  ('width', 100))]

But it is not in the keys:

((Pdb)) pp self.storage.keys()
[(('direction', 'down'),
  ('fieldname', 'image'),
  ('height', 105),
  ('width', 105)),
 'd891e734-b164-4e30-90c1-991bd51cadf0',
 '3ceb8c33-17a3-40ba-aae5-db7445eee2a0',
 (('direction', 'down'),
  ('fieldname', 'footerImage'),
  ('height', 500),
  ('width', 1500)),
 (('direction', 'down'),
  ('fieldname', 'image'),
  ('height', 100),
  ('width', 100))]

So the delete fails.

It's easy to add an extra check to avoid the traceback. I'l probably make a pull request for that.

But it is strange that the keys and values can get out of sync. It could have something to do with RelStorage. Or that this is for two zope instances, with the blobstorage on a shared network drive.

Confusing modes `contain` and `cover` (to me at least)

I just wondered why the plone.scale modes contain and cover are the direct opposite of the css object-fit meanings?

contain

plone.scale fills width/height completely and image gets clipped out of the center
object-fit scales image to fit width or height and gets letterboxed

cover

plone.scale scales image to fit width or height
object-fit fills width/height and gets clipped according to the container

Note to myself: documentation needs update on this too ... see https://6.docs.plone.org/classic-ui/images.html#scaling-direction ... direction is obsolete and should not be used anymore.

storage.py _cleanup TypeError: unsupported operand type(s) for -: 'str' and 'int'

Hi, i get an error while rendering an template with Images. I use Plone 4.3.9. Please no irritations because of the path in the traceback.

  File "/opt/Plone-4.3.3/buildout-cache/eggs/plone.scale-1.4.1-py2.7.egg/plone/scale/storage.py", line 166, in scale
    self._cleanup()
  File "/opt/Plone-4.3.3/buildout-cache/eggs/plone.scale-1.4.1-py2.7.egg/plone/scale/storage.py", line 190, in _cleanup
    value['modified'] < modified_time - KEEP_SCALE_MILLIS):
TypeError: unsupported operand type(s) for -: 'str' and 'int'

# Here my Debug Output of the Values:
2016-08-27 18:58:05 INFO plone.scale key: d7620496-5e61-4f6b-8490-b30399d809ba
2016-08-27 18:58:05 INFO plone.scale modified time     1467291549.8024411467291549.8028791467291549.8032841467291549.8036901467291549.804092
2016-08-27 18:58:05 INFO plone.scale value['modified'] 1467291549.8024411467291549.8028791467291549.8032841467291549.8036901467291549.804092

I think it's not an Integer, all values are 'str'. The comparison but needs integer values . What should i do? Should I overwrite the _cleanup Method and purge the Storage every time?

Incompatible with Pillow 10.1+

Plone 6 uses Pillow 9.5. In 10.1.0 an incompatible change was made that causes an error in the tests:

Error in test testAlphaForcesPNG (plone.scale.tests.test_scale.ScalingTests.testAlphaForcesPNG)
Traceback (most recent call last):
  File "/Users/maurits/.pyenv/versions/3.12.1/lib/python3.12/unittest/case.py", line 58, in testPartExecutor
    yield
  File "/Users/maurits/.pyenv/versions/3.12.1/lib/python3.12/unittest/case.py", line 636, in run
    self._callTestMethod(testMethod)
  File "/Users/maurits/.pyenv/versions/3.12.1/lib/python3.12/unittest/case.py", line 589, in _callTestMethod
    if method() is not None:
  File "/Users/maurits/community/plone-coredev/6.1/src/plone.scale/plone/scale/tests/test_scale.py", line 63, in testAlphaForcesPNG
    self.assertEqual(scaleImage(result, 84, 103, "contain")[1], "JPEG")
  File "/Users/maurits/community/plone-coredev/6.1/src/plone.scale/plone/scale/scale.py", line 118, in scaleImage
    image, format_ = scaleSingleFrame(
  File "/Users/maurits/community/plone-coredev/6.1/src/plone.scale/plone/scale/scale.py", line 177, in scaleSingleFrame
    image.mode = "RGB"
AttributeError: property 'mode' of 'Image' object has no setter

This is when handling a JPEG image in RGBA mode where the "A" part (Alpha) is not really uses, to we convert it to RGB mode.

Apparently we should use image = image.convert("RGB") now. The tests then pass with both Pillow 9 and 10. I will create a PR.

DeprecationWarning: ANTIALIAS is deprecated and will be removed in Pillow 10

You get this warning when you use Pillow 9.1.0:

DeprecationWarning: ANTIALIAS is deprecated and will be removed in Pillow 10 (2023-07-01).
Use Resampling.LANCZOS instead.
  (dimensions.final_width, dimensions.final_height), PIL.Image.ANTIALIAS

Since we try to keep current master of plone.scale also working on Plone 5.2 Py 3, we may need some conditional handling.

Remove deprecated factory handler

In storage.py we support passing a factory to the scale method. When you use this, we print a warning:

Deprecated usage of factory in plone.scale. Provide an adapter for the factory instead. The kwarg will be dropped with plone.scale 3.0.

Instead it is still there in latest official release 3.1.2. So let's remove it in version 4 then. I will make a PR.
I have already released a 4.0.0a1 today, for Python 3 only. Still works on 5.2 as well, for those who want it.

Current plone.app.tiles still uses the deprecated way, which is probably one reason why it was not removed yet. I can update this package. That should be possible when using plone.namedfile 6.0.0a2.

Modernize plone.scale, make AnnotationStorage an adapter

Low hanging fruit:

  • Make it Python 3.7+, Plone 6 only. (Well, might work on 5.2 Py 3 as well. The package itself does not do anything with the rest of Plone, expect importing plone.testing in the tests.)
  • black, isort5, pyupgrade
  • Remove the docs directory and the [sphinx] extra. The last real update is from 2010. The text from the index has been included in the readme, and the rest is not interesting, and outdated. Hosted here: https://pythonhosted.org/plone.scale/
  • GitHub Actions may be nice here, since the package does not use Plone, and advertises itself as supporting "Zope 2, grok and other systems build on using the Zope ToolKit".

And then the interesting one: register AnnotationStorage as an adapter.

AnnotationStorage is defined like this:

@implementer(IImageScaleStorage)
class AnnotationStorage(MutableMapping):

But there is no zcml, so this is never registered as an adapter.
So plone.namedfile has to call AnnotationStorage directly instead of doing an adapter lookup.
With an adapter lookup in place, I can register a different adapter for tiles. Currently plone.app.tiles defines its own annotation storage which it uses in publishTraverse and in scale. This is one of the reasons that plone.app.tiles copies over so many code from plone.namedfile.

If we register AnnotationStorage as an adapter, we solve this problem. And it seems logical.

What do you think?

Damaged images fail on scale.

Damaged images fail on scale, this info should somehow be shown to the user...

IOError: image file is truncated (56 bytes not processed)
  File "plone/buildout/eggs/plone.namedfile-4.1-py2.7.egg/plone/namedfile/scaling.py", line 220, in __call__
    **parameters
  File "plone/buildout/src-addons/plone.app.imagecropping/src/plone/app/imagecropping/dx.py", line 48, in create_scale
    **parameters
  File "plone/buildout/eggs/plone.namedfile-4.1-py2.7.egg/plone/namedfile/scaling.py", line 170, in create_scale
    **parameters
  File "plone/buildout/src/plone.scale/plone/scale/scale.py", line 51, in scaleImage
    image = scalePILImage(image, width, height, direction)
  File "plone/buildout/src/plone.scale/plone/scale/scale.py", line 164, in scalePILImage
    return _scale_thumbnail(image, width, height)
  File "plone/buildout/src/plone.scale/plone/scale/scale.py", line 98, in _scale_thumbnail
    image.thumbnail((width, height), PIL.Image.ANTIALIAS)
  File "PIL/Image.py", line 1800, in thumbnail
    im = self.resize(size, resample)
  File "PIL/Image.py", line 1533, in resize
    self.load()
  File "PIL/ImageFile.py", line 222, in load
    "(%d bytes not processed)" % len(b))

Refactor CI: just use pip, no mxdev

We use mxdev in this package. This is needed because we want to use the core Plone 5.2/6.0 constraints, and need to ignore plone.scale from the constraints. Nice example, at least for me.
But our only dependencies are setuptools and Pillow. mxdev is overkill then. We should simply test a few combinations of Python and Pillow versions.

Duplicate scales are generated when the image hasn't been modified

Steps to reproduce:

  1. Create a new Plone 6 classic site
  2. Add an Image content item and save
  3. Run find var/blobstorage -name '*.blob'
  4. Edit the Image content item and change something other than the image itself (e.g. description), then save.
  5. Run find var/blobstorage -name '*.blob' again

Expected: After initial creation of the image, there should be 2 blobs (the full size image and the large scale that was generated when viewing the image). After editing and saving again, there should be 3 blobs (the first 2, plus the preview scale that was generated while viewing the edit form).

Actual: After editing and saving, there are 5 blobs. One of them is identical to the large scale that existed before (there are now 2 copies of it). The other one is a mini scale, but I'm less concerned about that; I just haven't found what caused it to be generated.

I think the duplicate scale is generated because the hash used when generating the scale is based on the modification time of the image content item rather than the modification time of the NamedBlobImage value stored in the image field. That can probably be fixed here: https://github.com/plone/plone.namedfile/blob/master/plone/namedfile/scaling.py#L497 No, that doesn't make sense because we should have the field name. I need to pull out the debugger to see why the hash is changing.

Error scaling BMP images in Plone 5.1.5

When calling a scale on a .bmp image I get this error.

Could not scale "<plone.namedfile.file.NamedBlobImage object at 0x7f3dbe51c758>" of <bound method Image.absolute_url of <Image at /Plone/cobweb.bmp>>
Traceback (most recent call last):
  File "/sprj/st_zope_plone5/buildouts/eggs/plone.namedfile-4.2.6-py2.7.egg/plone/namedfile/scaling.py", line 253, in __call__
    **parameters
  File "/sprj/st_zope_plone5/buildouts/eggs/plone.namedfile-4.2.6-py2.7.egg/plone/namedfile/scaling.py", line 200, in create_scale
    **parameters
  File "/sprj/st_zope_plone5/buildouts/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 74, in scaleImage
    if all(rgb[0] == rgb[1] == rgb[2] for c, rgb in colors):
  File "/sprj/st_zope_plone5/buildouts/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 74, in <genexpr>
    if all(rgb[0] == rgb[1] == rgb[2] for c, rgb in colors):
IndexError: tuple index out of range

I dug into this a bit in a debugger.

>>> img=app.unrestrictedTraverse('/Plone/cobweb.bmp')
>>> portrait=img.portrait
>>> from plone.scale.scale import scaleImage
>>> scaleImage(portrait.data, 16, 16)

This gives the same error as above. the value of image.format is "BMP" which will cause the scale to assume converting into JPEG. This triggers a later condition where it tries to check the RGB values for equality to determine if it's gray.

>>> import PIL.Image
>>> from StringIO import StringIO
>>> image = PIL.Image.open(StringIO(portrait.data))
>>> colors = image.getcolors(maxcolors=256)
>>> colors
[(59, (255, 255)), (8, (253, 255)), (4, (251, 255)), (4, (249, 255)), (3, (247, 255)), (2, (245, 255)), (1, (241, 255)), (3, (237, 255)), (1, (235, 255)), (2, (227, 255)), (2, (225, 255)), (2, (223, 255)), (3, (217, 255)), (2, (211, 255)), (2, (209, 255)), (1, (205, 255)), (1, (201, 255)), (1, (199, 255)), (1, (183, 255)), (1, (181, 255)), (1, (177, 255)), (1, (167, 255)), (1, (163, 255)), (2, (159, 255)), (1, (157, 255)), (1, (151, 255)), (1, (149, 255)), (2, (147, 255)), (1, (143, 255)), (1, (139, 255)), (1, (135, 255)), (2, (125, 255)), (1, (121, 255)), (2, (113, 255)), (1, (109, 255)), (1, (101, 255)), (1, (99, 255)), (1, (97, 255)), (1, (95, 255)), (2, (93, 255)), (3, (87, 255)), (1, (79, 255)), (1, (77, 255)), (3, (73, 255)), (1, (69, 255)), (1, (65, 255)), (2, (61, 255)), (2, (59, 255)), (1, (53, 255)), (1, (51, 255)), (1, (47, 255)), (2, (37, 255)), (1, (31, 255)), (1, (29, 255)), (10, (25, 255)), (2, (21, 255)), (1, (19, 255)), (2, (17, 255)), (3, (15, 255)), (1, (13, 255)), (2, (9, 255)), (1, (7, 255)), (1, (5, 255)), (1, (1, 255)), (2, (254, 255)), (5, (252, 255)), (2, (250, 255)), (2, (248, 255)), (1, (246, 255)), (5, (244, 255)), (2, (242, 255)), (1, (228, 255)), (1, (226, 255)), (2, (224, 255)), (1, (218, 255)), (1, (214, 255)), (2, (212, 255)), (2, (210, 255)), (1, (206, 255)), (1, (200, 255)), (2, (196, 255)), (1, (194, 255)), (1, (188, 255)), (1, (186, 255)), (1, (168, 255)), (1, (164, 255)), (1, (138, 255)), (1, (136, 255)), (1, (134, 255)), (1, (132, 255)), (1, (130, 255)), (1, (128, 255)), (1, (124, 255)), (1, (122, 255)), (2, (118, 255)), (1, (110, 255)), (1, (108, 255)), (1, (106, 255)), (1, (94, 255)), (1, (88, 255)), (1, (86, 255)), (2, (84, 255)), (1, (78, 255)), (1, (72, 255)), (1, (70, 255)), (1, (56, 255)), (1, (54, 255)), (2, (50, 255)), (1, (38, 255)), (1, (30, 255)), (3, (28, 255)), (1, (26, 255)), (1, (24, 255)), (2, (22, 255)), (1, (18, 255)), (1, (16, 255)), (2, (6, 255)), (1, (2, 255)), (6, (0, 255))]

As you can see the rgb values only have two values so rgb[2] throws an IndexError

Conflict error on image_scales indexing when uploading an image via `plone.restapi`

BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)

Conflict error on image_scales indexing when uploading an image via plone.restapi, then the image fails to show in a block.

I downgraded to 6.0.6 and it does not happens.

/cc @davisagli @ericof @mauritsvanrees @fredvd

What I did:

Using Plone 6.0.7 docker images, latest plone.restapi (9.0.0)

When uploading an image, there are randomly:

2023-09-29 10:16:20 ERROR [ZODB.ConflictResolution:307][waitress-0] Unexpected error while trying to resolve conflict on <class 'plone.scale.storage.ScalesDict'>
Traceback (most recent call last):
  File "/app/lib/python3.11/site-packages/ZODB/ConflictResolution.py", line 290, in tryToResolveConflict
    resolved = resolve(old, committed, newstate)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.11/site-packages/plone/scale/storage.py", line 119, in _p_resolveConflict
    self.raise_conflict(saved[key], new[key])
                        ~~~~~^^^^^
KeyError: 'image-1000-ab703699e343ff030a3cc014950e6ada'

Which causes that the scales are not there, then the newly uploaded image fails to show:

image

What I expect to happen:

The scales are in indexed the catalog correctly on upload.

Cleanup does wrong time comparison

We are trying to clean up scales that are more than a day out of date. This time was chosen because possibly old cached html might still be referencing a by now outdated scale: if you are seeing old html it is better to see an old image too instead of no image.

But the code thinks the modified time is measured in milli seconds. And actually it is in seconds. I was the one who actually added this code...

Either I was wrong then or I am wrong now.

So before I change anything: can someone check this? Is the modified time expected to be in seconds or in milliseconds?

New image scale sizes break cropping

In Plone 6, cropping an image to the thumb scale works fine: you get a 128x128 image.

But how about the new preview scale? It is defined as 400 by 65536. That makes no sense for cropping. I saw this when adding tests.
So how should we handle this? I propose:

  • When asking for a crop (mode="contain")
  • and the asked height is 65536 (or -1, or None)
  • then we crop to a square: use the asked for width also for the height.

I have a branch ready.

"ValueError: height and width must be > 0" for tiff files

2019-12-02 10:53:31 ERROR plone.namedfile.scaling Could not scale "<plone.namedfile.file.NamedBlobImage object at 0x11a532cf8>" of 'http://localhost:12481/plone/intern/shop/rechtsquellen-1'
Traceback (most recent call last):
  File "/Users/peter/workspace/test/eggs/plone.namedfile-5.2.0-py2.7.egg/plone/namedfile/scaling.py", line 245, in __call__
    **parameters
  File "/Users/peter/workspace/test/eggs/plone.namedfile-5.2.0-py2.7.egg/plone/namedfile/scaling.py", line 195, in create_scale
    **parameters
  File "/Users/peter/workspace/test/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 67, in scaleImage
    image = scalePILImage(image, width, height, direction)
  File "/Users/peter/workspace/test/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 194, in scalePILImage
    return _scale_thumbnail(image, width, height)
  File "/Users/peter/workspace/test/eggs/plone.scale-3.0.3-py2.7.egg/plone/scale/scale.py", line 128, in _scale_thumbnail
    image.thumbnail((width, height), PIL.Image.ANTIALIAS)
  File "/Users/peter/workspace/test/eggs/Pillow-6.2.1-py2.7-macosx-10.13-x86_64.egg/PIL/Image.py", line 2219, in thumbnail
    im = self.resize(size, resample)
  File "/Users/peter/workspace/test/eggs/Pillow-6.2.1-py2.7-macosx-10.13-x86_64.egg/PIL/Image.py", line 1883, in resize
    im = im.resize(size, resample, box)
  File "/Users/peter/workspace/test/eggs/Pillow-6.2.1-py2.7-macosx-10.13-x86_64.egg/PIL/Image.py", line 1888, in resize
    return self._new(self.im.resize(size, resample, box))
ValueError: height and width must be > 0

I'm getting this error but scales are created und can be displayed

With Plone 5.1.5 and with the packages used in 5.2.
What's the state of support for tiff files?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.