From 696f865bcb24bad6403d3062ef481184b4861f35 Mon Sep 17 00:00:00 2001 From: gtrivedi Date: Sat, 22 Mar 2014 13:17:43 -0400 Subject: [PATCH 1/5] Added flipped support in image_io --- kivy/core/image/__init__.py | 1 + kivy/core/image/img_imageio.pyx | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index 850414bfd..6a1c8aa76 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -740,6 +740,7 @@ class Image(EventDispatcher): fmt = 'rgba' else: raise Exception('Unable to determine the format of the pixels') + Logger.debug('Calling <%s>.save: Vertical flip <%s>' % (str(loader), str(flipped))) return loader.save(filename, size[0], size[1], fmt, pixels, flipped) def read_pixel(self, x, y): diff --git a/kivy/core/image/img_imageio.pyx b/kivy/core/image/img_imageio.pyx index 9c115b2e2..463620618 100644 --- a/kivy/core/image/img_imageio.pyx +++ b/kivy/core/image/img_imageio.pyx @@ -91,6 +91,10 @@ cdef extern from "CoreGraphics/CGColorSpace.h": CGColorSpaceRef CGColorSpaceCreateDeviceRGB() void CGColorSpaceRelease(CGColorSpaceRef cs) +cdef extern from "CoreGraphics/CGAffineTransform.h": + ctypedef void *CGAffineTransform + CGAffineTransform CGAffineTransformMake (float, float, float, float, float, float) + cdef extern from "CoreGraphics/CGContext.h": ctypedef void *CGContextRef void CGContextRelease(CGContextRef c) @@ -98,6 +102,7 @@ cdef extern from "CoreGraphics/CGContext.h": int kCGBlendModeCopy int kCGBlendModeNormal void CGContextSetBlendMode(CGContextRef, int) + void CGContextConcatCTM (CGContextRef, CGAffineTransform) cdef extern from "CoreGraphics/CGBitmapContext.h": CGImageRef CGBitmapContextCreateImage(CGColorSpaceRef) @@ -181,11 +186,11 @@ def load_image_data(bytes _url): return (width, height, 'rgba', r_data) -def save_image_rgba(filename, width, height, data): +def save_image_rgba(filename, width, height, data, flipped): # compatibility, could be removed i guess - save_image(filename, width, height, 'rgba', data) + save_image(filename, width, height, 'rgba', data, flipped) -def save_image(filename, width, height, fmt, data): +def save_image(filename, width, height, fmt, data, flipped): # save a RGBA string into filename using CoreGraphics # FIXME only png output are accepted. @@ -219,6 +224,10 @@ def save_image(filename, width, height, fmt, data): colorSpace, kCGImageAlphaNoneSkipLast) + cdef CGAffineTransform flipMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, height) + if flipped: + CGContextConcatCTM(bitmapContext, flipMatrix) + cdef CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext) cdef char *cfilename = filename @@ -267,8 +276,8 @@ class ImageLoaderImageIO(ImageLoaderBase): return True @staticmethod - def save(filename, width, height, fmt, pixels): - save_image(filename, width, height, fmt, pixels) + def save(filename, width, height, fmt, pixels, flipped): + save_image(filename, width, height, fmt, pixels, flipped) return True # register From 2406b864a4eeec78203024fa00d05f5ae028fcdc Mon Sep 17 00:00:00 2001 From: gtrivedi Date: Sun, 23 Mar 2014 16:55:18 -0400 Subject: [PATCH 2/5] Actually flipping image by drawing into a new context --- kivy/core/image/__init__.py | 2 +- kivy/core/image/img_imageio.pyx | 36 ++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index 6a1c8aa76..0951d1c0b 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -740,7 +740,7 @@ class Image(EventDispatcher): fmt = 'rgba' else: raise Exception('Unable to determine the format of the pixels') - Logger.debug('Calling <%s>.save: Vertical flip <%s>' % (str(loader), str(flipped))) + Logger.debug('Image%s: Saving with vertical flip <%s>' % (loader.__name__[11:], str(flipped))) return loader.save(filename, size[0], size[1], fmt, pixels, flipped) def read_pixel(self, x, y): diff --git a/kivy/core/image/img_imageio.pyx b/kivy/core/image/img_imageio.pyx index 463620618..b56d0d4a1 100644 --- a/kivy/core/image/img_imageio.pyx +++ b/kivy/core/image/img_imageio.pyx @@ -102,7 +102,7 @@ cdef extern from "CoreGraphics/CGContext.h": int kCGBlendModeCopy int kCGBlendModeNormal void CGContextSetBlendMode(CGContextRef, int) - void CGContextConcatCTM (CGContextRef, CGAffineTransform) + void CGContextConcatCTM(CGContextRef, CGAffineTransform) cdef extern from "CoreGraphics/CGBitmapContext.h": CGImageRef CGBitmapContextCreateImage(CGColorSpaceRef) @@ -224,10 +224,6 @@ def save_image(filename, width, height, fmt, data, flipped): colorSpace, kCGImageAlphaNoneSkipLast) - cdef CGAffineTransform flipMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, height) - if flipped: - CGContextConcatCTM(bitmapContext, flipMatrix) - cdef CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext) cdef char *cfilename = filename @@ -241,8 +237,34 @@ def save_image(filename, width, height, fmt, data, flipped): cdef CGImageDestinationRef dest = CGImageDestinationCreateWithURL(url, ctype, 1, NULL) - # release everything - CGImageDestinationAddImage(dest, cgImage, NULL) + # copy the image into a transformed context + cdef CGContextRef flippedContext + cdef CGImageRef newImageRef + + if flipped: + flippedContext = CGBitmapContextCreate( + NULL, width, height, + 8, # bitsPerComponent + fmt_length * width, # bytesPerRow + colorSpace, + kCGImageAlphaNoneSkipLast) + + CGContextConcatCTM(flippedContext, CGAffineTransformMake(1.0, 0.0, + 0.0, -1.0, + 0.0, height)) + + CGContextDrawImage(flippedContext, + CGRectMake(0, 0, width, height), + cgImage) + + newImageRef = CGBitmapContextCreateImage(flippedContext) + CGImageDestinationAddImage(dest, newImageRef, NULL) + CFRelease(newImageRef) + CFRelease(flippedContext) + else: + CGImageDestinationAddImage(dest, cgImage, NULL) + + #Release everything CFRelease(cgImage) CFRelease(bitmapContext) CFRelease(colorSpace) From 05712ba2d9003a955b02892e6f4556fe73bcc6c9 Mon Sep 17 00:00:00 2001 From: gtrivedi Date: Thu, 27 Mar 2014 23:11:12 -0400 Subject: [PATCH 3/5] Removed debug print --- kivy/core/image/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index 0951d1c0b..61d7fbe94 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -182,7 +182,7 @@ class ImageLoaderBase(object): imagedata = self._data[count] imagedata.source = '{}{}|{}'.format( 'zip|' if self.filename.endswith('.zip') else '', - self._nocache, uid) + self._nocache, uid) texture = Texture.create_from_data( imagedata, mipmap=self._mipmap) if not self._nocache: @@ -740,7 +740,6 @@ class Image(EventDispatcher): fmt = 'rgba' else: raise Exception('Unable to determine the format of the pixels') - Logger.debug('Image%s: Saving with vertical flip <%s>' % (loader.__name__[11:], str(flipped))) return loader.save(filename, size[0], size[1], fmt, pixels, flipped) def read_pixel(self, x, y): From 8fb95cd266c312bc7236e489045fda423b4ce8b2 Mon Sep 17 00:00:00 2001 From: gtrivedi Date: Thu, 27 Mar 2014 23:12:59 -0400 Subject: [PATCH 4/5] Fixed tabbing as per PEP8 checker --- kivy/core/image/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kivy/core/image/__init__.py b/kivy/core/image/__init__.py index 61d7fbe94..ec5ec03f0 100644 --- a/kivy/core/image/__init__.py +++ b/kivy/core/image/__init__.py @@ -182,7 +182,7 @@ class ImageLoaderBase(object): imagedata = self._data[count] imagedata.source = '{}{}|{}'.format( 'zip|' if self.filename.endswith('.zip') else '', - self._nocache, uid) + self._nocache, uid) texture = Texture.create_from_data( imagedata, mipmap=self._mipmap) if not self._nocache: From 510fadb7c20dc9095eda33a5fe96be39c875d5b8 Mon Sep 17 00:00:00 2001 From: gtrivedi Date: Thu, 27 Mar 2014 23:14:29 -0400 Subject: [PATCH 5/5] Fixed CFRelease order --- kivy/core/image/img_imageio.pyx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kivy/core/image/img_imageio.pyx b/kivy/core/image/img_imageio.pyx index b56d0d4a1..8309d4966 100644 --- a/kivy/core/image/img_imageio.pyx +++ b/kivy/core/image/img_imageio.pyx @@ -93,7 +93,7 @@ cdef extern from "CoreGraphics/CGColorSpace.h": cdef extern from "CoreGraphics/CGAffineTransform.h": ctypedef void *CGAffineTransform - CGAffineTransform CGAffineTransformMake (float, float, float, float, float, float) + CGAffineTransform CGAffineTransformMake(float a, float b, float c, float d, float tx, float ty) cdef extern from "CoreGraphics/CGContext.h": ctypedef void *CGContextRef @@ -102,7 +102,7 @@ cdef extern from "CoreGraphics/CGContext.h": int kCGBlendModeCopy int kCGBlendModeNormal void CGContextSetBlendMode(CGContextRef, int) - void CGContextConcatCTM(CGContextRef, CGAffineTransform) + void CGContextConcatCTM(CGContextRef fc, CGAffineTransform matrix) cdef extern from "CoreGraphics/CGBitmapContext.h": CGImageRef CGBitmapContextCreateImage(CGColorSpaceRef) @@ -259,16 +259,17 @@ def save_image(filename, width, height, fmt, data, flipped): newImageRef = CGBitmapContextCreateImage(flippedContext) CGImageDestinationAddImage(dest, newImageRef, NULL) + CGImageDestinationFinalize(dest) CFRelease(newImageRef) CFRelease(flippedContext) else: CGImageDestinationAddImage(dest, cgImage, NULL) - + CGImageDestinationFinalize(dest) + #Release everything CFRelease(cgImage) CFRelease(bitmapContext) CFRelease(colorSpace) - CGImageDestinationFinalize(dest) free(pixels) class ImageLoaderImageIO(ImageLoaderBase): @@ -298,7 +299,7 @@ class ImageLoaderImageIO(ImageLoaderBase): return True @staticmethod - def save(filename, width, height, fmt, pixels, flipped): + def save(filename, width, height, fmt, pixels, flipped=False): save_image(filename, width, height, fmt, pixels, flipped) return True