mirror of https://github.com/kivy/kivy.git
Merge pull request #2358 from matham/ffpy-image
Add ffpyplayer provider for image
This commit is contained in:
commit
6bcaecdf18
|
@ -186,7 +186,7 @@ kivy_options = {
|
|||
'video': ('gstplayer', 'ffmpeg', 'ffpyplayer', 'gi', 'pygst', 'pyglet',
|
||||
'null'),
|
||||
'audio': ('gstplayer', 'pygame', 'gi', 'pygst', 'ffpyplayer', 'sdl'),
|
||||
'image': ('tex', 'imageio', 'dds', 'gif', 'pil', 'pygame'),
|
||||
'image': ('tex', 'imageio', 'dds', 'gif', 'pil', 'pygame', 'ffpy'),
|
||||
'camera': ('opencv', 'gi', 'pygst', 'videocapture', 'avfoundation'),
|
||||
'spelling': ('enchant', 'osxappkit', ),
|
||||
'clipboard': ('android', 'pygame', 'dummy'), }
|
||||
|
|
|
@ -40,13 +40,13 @@ class ImageData(object):
|
|||
The container will always have at least the mipmap level 0.
|
||||
'''
|
||||
|
||||
__slots__ = ('fmt', 'mipmaps', 'source', 'flip_vertical')
|
||||
__slots__ = ('fmt', 'mipmaps', 'source', 'flip_vertical', 'source_image')
|
||||
_supported_fmts = ('rgb', 'rgba', 'bgr', 'bgra', 's3tc_dxt1', 's3tc_dxt3',
|
||||
's3tc_dxt5', 'pvrtc_rgb2', 'pvrtc_rgb4', 'pvrtc_rgba2',
|
||||
'pvrtc_rgba4', 'etc1_rgb8')
|
||||
|
||||
def __init__(self, width, height, fmt, data, source=None,
|
||||
flip_vertical=True):
|
||||
flip_vertical=True, source_image=None):
|
||||
assert fmt in ImageData._supported_fmts
|
||||
|
||||
#: Decoded image format, one of a available texture format
|
||||
|
@ -62,10 +62,14 @@ class ImageData(object):
|
|||
#: Indicate if the texture will need to be vertically flipped
|
||||
self.flip_vertical = flip_vertical
|
||||
|
||||
# the original image, which we might need to save if it is a memoryview
|
||||
self.source_image = source_image
|
||||
|
||||
def release_data(self):
|
||||
mm = self.mipmaps
|
||||
for item in mm.values():
|
||||
item[2] = None
|
||||
self.source_image = None
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
|
@ -445,7 +449,6 @@ class Image(EventDispatcher):
|
|||
else:
|
||||
raise Exception('Unable to load image type {0!r}'.format(arg))
|
||||
|
||||
|
||||
def remove_from_cache(self):
|
||||
'''Remove the Image from cache. This facilitates re-loading of
|
||||
images from disk in case the image content has changed.
|
||||
|
@ -797,6 +800,7 @@ image_libs += [
|
|||
('tex', 'img_tex'),
|
||||
('dds', 'img_dds'),
|
||||
('pygame', 'img_pygame'),
|
||||
('ffpy', 'img_ffpyplayer'),
|
||||
('pil', 'img_pil'),
|
||||
('gif', 'img_gif')]
|
||||
libs_loaded = core_register_libs('image', image_libs)
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
'''
|
||||
FFPyPlayer: FFmpeg based image loader
|
||||
'''
|
||||
|
||||
__all__ = ('ImageLoaderFFPy', )
|
||||
|
||||
import ffpyplayer
|
||||
from ffpyplayer.pic import ImageLoader as ffImageLoader, SWScale
|
||||
from ffpyplayer.tools import set_log_callback, loglevels, get_log_callback
|
||||
|
||||
from kivy.logger import Logger
|
||||
from kivy.core.image import ImageLoaderBase, ImageData, ImageLoader
|
||||
|
||||
|
||||
Logger.info('ImageLoaderFFPy: Using ffpyplayer {}'.format(ffpyplayer.version))
|
||||
|
||||
|
||||
logger_func = {'quiet': Logger.critical, 'panic': Logger.critical,
|
||||
'fatal': Logger.critical, 'error': Logger.error,
|
||||
'warning': Logger.warning, 'info': Logger.info,
|
||||
'verbose': Logger.debug, 'debug': Logger.debug}
|
||||
|
||||
|
||||
def _log_callback(message, level):
|
||||
message = message.strip()
|
||||
if message:
|
||||
logger_func[level]('ImageLoaderFFPy: {}'.format(message))
|
||||
|
||||
if not get_log_callback():
|
||||
set_log_callback(_log_callback)
|
||||
|
||||
|
||||
class ImageLoaderFFPy(ImageLoaderBase):
|
||||
'''Image loader based on the ffpyplayer library.
|
||||
|
||||
.. versionadded:: 1.8.1
|
||||
|
||||
.. note:
|
||||
This provider may support more formats than what is listed in
|
||||
:meth:`extensions`.
|
||||
'''
|
||||
|
||||
@staticmethod
|
||||
def extensions():
|
||||
'''Return accepted extensions for this loader'''
|
||||
# See https://www.ffmpeg.org/general.html#Image-Formats
|
||||
return ('bmp', 'dpx', 'exr', 'gif', 'ico', 'jpeg', 'jpg2000', 'jpg',
|
||||
'jls', 'pam', 'pbm', 'pcx', 'pgm', 'pgmyuv', 'pic', 'png',
|
||||
'ppm', 'ptx', 'sgi', 'ras', 'tga', 'tiff', 'webp', 'xbm',
|
||||
'xface', 'xwd')
|
||||
|
||||
def load(self, filename):
|
||||
try:
|
||||
loader = ffImageLoader(filename)
|
||||
except:
|
||||
Logger.warning('Image: Unable to load image <%s>' % filename)
|
||||
raise
|
||||
|
||||
# update internals
|
||||
self.filename = filename
|
||||
images = []
|
||||
|
||||
while True:
|
||||
frame, t = loader.next_frame()
|
||||
if frame is None:
|
||||
break
|
||||
images.append(frame)
|
||||
if not len(images):
|
||||
raise Exception('No image found in {}'.format(filename))
|
||||
|
||||
w, h = images[0].get_size()
|
||||
ifmt = images[0].get_pixel_format()
|
||||
if ifmt != 'rgba' and ifmt != 'rgb24':
|
||||
fmt = 'rgba'
|
||||
sws = SWScale(w, h, ifmt, ofmt=fmt)
|
||||
for i, image in enumerate(images):
|
||||
images[i] = sws.scale(image)
|
||||
else:
|
||||
fmt = ifmt if ifmt == 'rgba' else 'rgb'
|
||||
|
||||
return [ImageData(w, h, fmt, img.to_memoryview()[0], source_image=img)
|
||||
for img in images]
|
||||
|
||||
|
||||
# register
|
||||
ImageLoader.register(ImageLoaderFFPy)
|
|
@ -57,9 +57,10 @@ from kivy.properties import StringProperty, ObjectProperty, ListProperty, \
|
|||
AliasProperty, BooleanProperty, NumericProperty
|
||||
from kivy.logger import Logger
|
||||
|
||||
# delayed imports
|
||||
# delayed imports
|
||||
Loader = None
|
||||
|
||||
|
||||
class Image(Widget):
|
||||
'''Image class, see module documentation for more information.
|
||||
'''
|
||||
|
@ -322,8 +323,8 @@ class AsyncImage(Image):
|
|||
if not self.is_uri(source):
|
||||
source = resource_find(source)
|
||||
self._coreimage = image = Loader.image(source,
|
||||
nocache=self.nocache,
|
||||
mipmap=self.mipmap)
|
||||
nocache=self.nocache, mipmap=self.mipmap,
|
||||
anim_delay=self.anim_delay)
|
||||
image.bind(on_load=self._on_source_load)
|
||||
image.bind(on_texture=self._on_tex_change)
|
||||
self.texture = image.texture
|
||||
|
|
Loading…
Reference in New Issue