theatlantic / thumbor-video-engine

An engine and tools for manipulating videos with thumbor using ffmpeg
https://thumbor-video-engine.readthedocs.io/
Other
31 stars 11 forks source link

Problems with thumbor.filters.fill #12

Closed elefante closed 2 days ago

elefante commented 1 year ago

First I would like to thank you for your project!

I have a problem when I try to use the filter thumbor.filters.fill. For some reason it doesn't work. When I go back to using the default engine, the filter works without problems.

I am using the minimalcompact/thumbor image, from hub.docker.com

Here's an example of what's happening

https://example.com/0x0:192x192/260x260/filters:still():format(jpeg):quality(10):fill(blue,1)/example.png

Here is the filter configuration of my container:

['thumbor_video_engine.filters.format','thumbor_video_engine.filters.still','thumbor.filters.fill',]

The log from container after access the URL

---> Starting thumbor solo...
--
2022-10-18 18:23:22 thumbor:DEBUG XXX INIT '<thumbor_video_engine.engines.video.Engine object at 0x7ff0246fad90>'
2022-10-18 18:23:22 thumbor:DEBUG XXX INIT '<thumbor.context.Context instance at 0x7ff0247475a0>'
2022-10-18 18:23:23 root:DEBUG thumbor starting at 0.0.0.0:80
2022-10-18 18:26:53 thumbor:DEBUG XXX INIT '<thumbor_video_engine.engines.video.Engine object at 0x7ff0245b7b10>'
2022-10-18 18:26:53 thumbor:DEBUG XXX INIT '<thumbor.context.Context instance at 0x7ff0246e81e0>'
2022-10-18 18:26:53 thumbor:DEBUG METRICS: inc: response.count:1
2022-10-18 18:26:53 thumbor:DEBUG [RESULT_STORAGE] getting from /data/result_storage/default/fb/6d/f956fb061d85680231e52caf4aee7cfb54b8
2022-10-18 18:26:53 thumbor:DEBUG [RESULT_STORAGE] image not found at /data/result_storage/default/fb/6d/f956fb061d85680231e52caf4aee7cfb54b8
2022-10-18 18:26:53 thumbor:DEBUG METRICS: timing: result_storage.incoming_time:0
2022-10-18 18:26:53 thumbor:DEBUG METRICS: inc: result_storage.miss:1
2022-10-18 18:26:53 thumbor:DEBUG Setting still frame at position 0
2022-10-18 18:26:53 thumbor:WARNING Setting format to jpeg
2022-10-18 18:26:53 thumbor:DEBUG Format specified: jpeg
2022-10-18 18:26:53 thumbor:DEBUG METRICS: inc: storage.hit:1
2022-10-18 18:26:53 thumbor:DEBUG XXX LOADER
2022-10-18 18:26:53 thumbor:DEBUG XXX LOAD INICIO '<thumbor.engines.pil.Engine object at 0x7ff0245c2190>'
2022-10-18 18:26:53 thumbor:DEBUG XXX LOAD INICIO '<thumbor.engines.pil.Engine object at 0x7ff0245c2210>'
2022-10-18 18:26:53 thumbor:DEBUG Set engine to thumbor.engines.pil (extension .jpg)
2022-10-18 18:26:53 thumbor:DEBUG XXX LOAD FINAL '<thumbor.engines.pil.Engine object at 0x7ff024152310>'
2022-10-18 18:26:53 thumbor:DEBUG XXX LOAD FINAL '<thumbor.engines.pil.Engine object at 0x7ff0245c2210>'
2022-10-18 18:26:54 thumbor:DEBUG XXX INIT '<thumbor_video_engine.engines.video.Engine object at 0x7ff024164bd0>'
2022-10-18 18:26:54 thumbor:DEBUG XXX INIT '<thumbor.context.Context instance at 0x7ff0246e81e0>'
2022-10-18 18:26:54 thumbor:DEBUG XXX GET ATTR '{'engine': None, 'ffmpeg_handle_animated_gif': True, 'ffmpeg_handle_animated_webp': True, 'use_gif_engine': False, 'context': <thumbor.context.Context instance at 0x7ff0246e81e0>}'
2022-10-18 18:26:54 thumbor:DEBUG XXX GET ATTR '<thumbor_video_engine.engines.video.Engine object at 0x7ff024164bd0>'
2022-10-18 18:26:54 tornado.application:ERROR Future exception was never retrieved: Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 307, in wrapper
yielded = next(result)
File "/usr/local/lib/python2.7/site-packages/thumbor/transformer.py", line 138, in smart_detect
self.do_image_operations()
File "/usr/local/lib/python2.7/site-packages/thumbor/transformer.py", line 232, in do_image_operations
callback=inner
File "/usr/local/lib/python2.7/site-packages/thumbor/context.py", line 292, in queue
self._execute_in_foreground(operation, callback)
File "/usr/local/lib/python2.7/site-packages/thumbor/context.py", line 283, in _execute_in_foreground
callback(result)
File "/usr/local/lib/python2.7/site-packages/thumbor/transformer.py", line 228, in inner
self.done_callback()
File "/usr/local/lib/python2.7/site-packages/thumbor/handlers/__init__.py", line 263, in after_transform
self.filters_runner.apply_filters(thumbor.filters.PHASE_POST_TRANSFORM, self.finish_request)
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 91, in apply_filters
exec_one_filter()
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 90, in exec_one_filter
f.run(exec_one_filter)
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 202, in run
results.append(self.runnable_method(*self.params))
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 23, in wrapper
return fn(self, *args2)
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/fill.py", line 40, in fill
self.fill_engine.image = self.fill_engine.gen_image((bx, by), color)
File "/usr/local/lib/python2.7/site-packages/thumbor_video_engine/engines/video.py", line 138, in __getattr__
raise AttributeError("'Engine' object has no attribute '%s'" % attr)
AttributeError: 'Engine' object has no attribute 'gen_image'
2022-10-18 18:27:10 tornado.access:INFO 200 GET /healthcheck (172.31.28.9) 0.42ms
2022-10-18 18:27:10 tornado.access:INFO 200 GET /healthcheck (172.31.32.157) 0.36ms
2022-10-18 18:27:10 tornado.access:INFO 200 GET /healthcheck (172.31.7.53) 0.40ms
2022-10-18 18:27:23 thumbor:DEBUG XXX INIT '<thumbor_video_engine.engines.video.Engine object at 0x7ff024164910>'
2022-10-18 18:27:23 thumbor:DEBUG XXX INIT '<thumbor.context.Context instance at 0x7ff0245b5960>'
2022-10-18 18:27:23 thumbor:DEBUG METRICS: inc: response.count:1
2022-10-18 18:27:23 thumbor:DEBUG [RESULT_STORAGE] getting from /data/result_storage/default/fb/6d/f956fb061d85680231e52caf4aee7cfb54b8
2022-10-18 18:27:23 thumbor:DEBUG [RESULT_STORAGE] image not found at /data/result_storage/default/fb/6d/f956fb061d85680231e52caf4aee7cfb54b8
2022-10-18 18:27:23 thumbor:DEBUG METRICS: timing: result_storage.incoming_time:0
2022-10-18 18:27:23 thumbor:DEBUG METRICS: inc: result_storage.miss:1
2022-10-18 18:27:23 thumbor:DEBUG Setting still frame at position 0
2022-10-18 18:27:23 thumbor:WARNING Setting format to jpeg
2022-10-18 18:27:23 thumbor:DEBUG Format specified: jpeg
2022-10-18 18:27:23 thumbor:DEBUG METRICS: inc: storage.hit:1
2022-10-18 18:27:23 thumbor:DEBUG XXX LOADER
2022-10-18 18:27:23 thumbor:DEBUG XXX LOAD INICIO '<thumbor.engines.pil.Engine object at 0x7ff02410f650>'
2022-10-18 18:27:23 thumbor:DEBUG XXX LOAD INICIO '<thumbor.engines.pil.Engine object at 0x7ff02410f6d0>'
2022-10-18 18:27:23 thumbor:DEBUG Set engine to thumbor.engines.pil (extension .jpg)
2022-10-18 18:27:23 thumbor:DEBUG XXX LOAD FINAL '<thumbor.engines.pil.Engine object at 0x7ff02410f850>'
2022-10-18 18:27:23 thumbor:DEBUG XXX LOAD FINAL '<thumbor.engines.pil.Engine object at 0x7ff02410f6d0>'
2022-10-18 18:27:24 thumbor:DEBUG XXX INIT '<thumbor_video_engine.engines.video.Engine object at 0x7ff02410fb50>'
2022-10-18 18:27:24 thumbor:DEBUG XXX INIT '<thumbor.context.Context instance at 0x7ff0245b5960>'
2022-10-18 18:27:24 thumbor:DEBUG XXX GET ATTR '{'engine': None, 'ffmpeg_handle_animated_gif': True, 'ffmpeg_handle_animated_webp': True, 'use_gif_engine': False, 'context': <thumbor.context.Context instance at 0x7ff0245b5960>}'
2022-10-18 18:27:24 thumbor:DEBUG XXX GET ATTR '<thumbor_video_engine.engines.video.Engine object at 0x7ff02410fb50>'
2022-10-18 18:27:24 tornado.application:ERROR Future exception was never retrieved: Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/tornado/gen.py", line 307, in wrapper
yielded = next(result)
File "/usr/local/lib/python2.7/site-packages/thumbor/transformer.py", line 138, in smart_detect
self.do_image_operations()
File "/usr/local/lib/python2.7/site-packages/thumbor/transformer.py", line 232, in do_image_operations
callback=inner
File "/usr/local/lib/python2.7/site-packages/thumbor/context.py", line 292, in queue
self._execute_in_foreground(operation, callback)
File "/usr/local/lib/python2.7/site-packages/thumbor/context.py", line 283, in _execute_in_foreground
callback(result)
File "/usr/local/lib/python2.7/site-packages/thumbor/transformer.py", line 228, in inner
self.done_callback()
File "/usr/local/lib/python2.7/site-packages/thumbor/handlers/__init__.py", line 263, in after_transform
self.filters_runner.apply_filters(thumbor.filters.PHASE_POST_TRANSFORM, self.finish_request)
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 91, in apply_filters
exec_one_filter()
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 90, in exec_one_filter
f.run(exec_one_filter)
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 202, in run
results.append(self.runnable_method(*self.params))
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/__init__.py", line 23, in wrapper
return fn(self, *args2)
File "/usr/local/lib/python2.7/site-packages/thumbor/filters/fill.py", line 40, in fill
self.fill_engine.image = self.fill_engine.gen_image((bx, by), color)
File "/usr/local/lib/python2.7/site-packages/thumbor_video_engine/engines/video.py", line 138, in __getattr__
raise AttributeError("'Engine' object has no attribute '%s'" % attr)
AttributeError: 'Engine' object has no attribute 'gen_image'

Thank you for your help! Best regards!

genisd commented 1 year ago

Same problem here. When i switch to the video engine, then the following call fails with the same error message:

https://thumbor.example.com/unsafe/110x90/filters:fill(white)/https://example.com/example.png

Just to be sure, the image referenced here is a .png not a video. With the default image engine pil this suceeds just fine.

@elefante where you ever able to figure this out?

genisd commented 1 year ago

This is the stacktrace I'm getting

2023-07-10 14:30:04 thumbor:ERROR ERROR: Traceback (most recent call last):
  File "/home/thumbor/venv/lib/python3.11/site-packages/tornado/web.py", line 1786, in _execute
    result = await result
             ^^^^^^^^^^^^
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/handlers/imaging.py", line 119, in get
    return await self.check_image(kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/handlers/imaging.py", line 116, in check_image
    return await self.execute_image_operations()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/handlers/__init__.py", line 205, in execute_image_operations
    await self.get_image()
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/handlers/__init__.py", line 303, in get_image
    await self.after_transform()
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/handlers/__init__.py", line 344, in after_transform
    await self.filters_runner.apply_filters(
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/filters/__init__.py", line 121, in apply_filters
    await filter_to_run.run()
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/filters/__init__.py", line 218, in run
    results.append(await self.runnable_method(*self.params))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/filters/__init__.py", line 56, in wrapper
    return await filtered_function(self, *args2)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor/filters/fill.py", line 57, in fill
    self.fill_engine.image = self.fill_engine.gen_image(
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thumbor/venv/lib/python3.11/site-packages/thumbor_video_engine/engines/video.py", line 125, in __getattr__
    raise AttributeError("'Engine' object has no attribute '%s'" % attr)
AttributeError: 'Engine' object has no attribute 'gen_image'

The filter fill appears to call gen_image on the default engine, which (for this specific call) is the video engine

Muffinman commented 8 months ago

I'm also having this issue. Any work-around?

elefante commented 1 month ago

I finally understand what is happening with this project. The documentation makes you think that it is not necessary to include the filters that are used in the standard engine.

Here is the environment variables according to the documentation at https://thumbor-video-engine.readthedocs.io/en/latest/

To enable transcoding between formats, add 'thumbor_video_engine.filters.format' to your FILTERS setting. If 'thumbor.filters.format' is already present, replace it with the filter from this package.

ENGINE = 'thumbor_video_engine.engines.video'
FILTERS = [
    'thumbor_video_engine.filters.format',
    'thumbor_video_engine.filters.still',
]

I changed the environment variables to include the filters I need when manipulating images in the default thumbor engine

ENGINE = 'thumbor_video_engine.engines.video'
FILTERS = [
    'thumbor.filters.quality',
    'thumbor.filters.fill',
    'thumbor_video_engine.filters.format',
    'thumbor_video_engine.filters.still',
]

Also, I had to use a fork of this project. The fork is at this link: https://github.com/eighteen73/thumbor-video-engine

Muffinman commented 2 weeks ago

@elefante That Eighteen73 fork is mine, I have submitted a PR to get this fixed in this repo.

mpdude commented 6 days ago

Is #23 actually the same problem?

fdintino commented 6 days ago

I see the issue. It stems from the fact that the fill filter re-instantiates the engine here

https://github.com/thumbor/thumbor/blob/252c5b10ff4766b8a09e0a017a11cb9912bf557a/thumbor/filters/fill.py#L28

Normally, the engine has enough information to determine whether it's being used for an image or video, and so it is able to dispatch the method call to self.image_engine or self.video_engine, respectively. But it lacks that context in the fill filter function.

Having the base video engine extend the PIL engine causes failures elsewhere. The solution might be to have certain methods default to using the image_engine. I'll take a closer look at this.