diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-06-20 11:30:05 -0700 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-06-20 11:30:05 -0700 |
commit | 0b6a96fb37917f5811b901abef0f900eb00d1a72 (patch) | |
tree | ee74a237288ac66fa31da3f7f7a61fbee3c01d63 | |
parent | b4cda26f9d6a08f53ee4b6fd5356465cc703f76d (diff) | |
download | qtlocation-mapboxgl-0b6a96fb37917f5811b901abef0f900eb00d1a72.tar.gz |
[ios][macos] Directly decode image files to non-premultiplied alpha images. Use [NSImage CGImageForProposedRect:context:hints:] instead of drawing into a bitmap representation
-rw-r--r-- | platform/darwin/mbgl/util/image+MGLAdditions.hpp | 4 | ||||
-rw-r--r-- | platform/darwin/src/MGLImageSource.mm | 3 | ||||
-rw-r--r-- | platform/darwin/src/image.mm | 28 | ||||
-rw-r--r-- | platform/ios/src/UIImage+MGLAdditions.h | 2 | ||||
-rw-r--r-- | platform/ios/src/UIImage+MGLAdditions.mm | 4 | ||||
-rw-r--r-- | platform/macos/src/NSImage+MGLAdditions.h | 2 | ||||
-rw-r--r-- | platform/macos/src/NSImage+MGLAdditions.mm | 18 |
7 files changed, 49 insertions, 12 deletions
diff --git a/platform/darwin/mbgl/util/image+MGLAdditions.hpp b/platform/darwin/mbgl/util/image+MGLAdditions.hpp index c738b4523d..df962cf76d 100644 --- a/platform/darwin/mbgl/util/image+MGLAdditions.hpp +++ b/platform/darwin/mbgl/util/image+MGLAdditions.hpp @@ -10,3 +10,7 @@ CGImageRef CGImageFromMGLPremultipliedImage(mbgl::PremultipliedImage&&); // Creates a PremultipliedImage by copying the pixels of the CGImage. // Does not alter the retain count of the supplied CGImage. mbgl::PremultipliedImage MGLPremultipliedImageFromCGImage(CGImageRef); + +// Creates an UnassociatedImage by copying the pixels of the CGImage. +// Does not alter the retain count of the supplied CGImage. +mbgl::UnassociatedImage MGLUnassociatedImageFromCGImage(CGImageRef src); diff --git a/platform/darwin/src/MGLImageSource.mm b/platform/darwin/src/MGLImageSource.mm index 0a2dc2713f..5e56e84220 100644 --- a/platform/darwin/src/MGLImageSource.mm +++ b/platform/darwin/src/MGLImageSource.mm @@ -60,8 +60,7 @@ - (void)setImage:(MGLImage *)image { if (image != nullptr) { - mbgl::UnassociatedImage unassociatedImage = mbgl::util::unpremultiply(image.mgl_premultipliedImage); - self.rawSource->setImage(std::move(unassociatedImage)); + self.rawSource->setImage(image.mgl_unassociatedImage); } else { self.rawSource->setImage(mbgl::UnassociatedImage({0,0})); } diff --git a/platform/darwin/src/image.mm b/platform/darwin/src/image.mm index 57b680fbdb..72499b6fb6 100644 --- a/platform/darwin/src/image.mm +++ b/platform/darwin/src/image.mm @@ -81,6 +81,34 @@ mbgl::PremultipliedImage MGLPremultipliedImageFromCGImage(CGImageRef src) { return image; } +mbgl::UnassociatedImage MGLUnassociatedImageFromCGImage(CGImageRef src) { + const size_t width = CGImageGetWidth(src); + const size_t height = CGImageGetHeight(src); + + mbgl::UnassociatedImage image({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) }); + + CGColorSpaceHandle colorSpace(CGColorSpaceCreateDeviceRGB()); + if (!colorSpace) { + throw std::runtime_error("CGColorSpaceCreateDeviceRGB failed"); + } + + constexpr const size_t bitsPerComponent = 8; + constexpr const size_t bytesPerPixel = 4; + const size_t bytesPerRow = bytesPerPixel * width; + + CGContextHandle context(CGBitmapContextCreate( + image.data.get(), width, height, bitsPerComponent, bytesPerRow, *colorSpace, + kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast)); + if (!context) { + throw std::runtime_error("CGBitmapContextCreate failed"); + } + + CGContextSetBlendMode(*context, kCGBlendModeCopy); + CGContextDrawImage(*context, CGRectMake(0, 0, width, height), src); + + return image; +} + namespace mbgl { PremultipliedImage decodeImage(const std::string& source) { diff --git a/platform/ios/src/UIImage+MGLAdditions.h b/platform/ios/src/UIImage+MGLAdditions.h index 6e15e07cb5..aeaf0f226f 100644 --- a/platform/ios/src/UIImage+MGLAdditions.h +++ b/platform/ios/src/UIImage+MGLAdditions.h @@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN - (mbgl::PremultipliedImage)mgl_premultipliedImage; +- (mbgl::UnassociatedImage)mgl_unassociatedImage; + @end NS_ASSUME_NONNULL_END diff --git a/platform/ios/src/UIImage+MGLAdditions.mm b/platform/ios/src/UIImage+MGLAdditions.mm index 5e28d18190..80e6373eaa 100644 --- a/platform/ios/src/UIImage+MGLAdditions.mm +++ b/platform/ios/src/UIImage+MGLAdditions.mm @@ -32,4 +32,8 @@ -(mbgl::PremultipliedImage)mgl_premultipliedImage { return MGLPremultipliedImageFromCGImage(self.CGImage); } + +- (mbgl::UnassociatedImage)mgl_unassociatedImage { + return MGLUnassociatedImageFromCGImage(self.CGImage); +} @end diff --git a/platform/macos/src/NSImage+MGLAdditions.h b/platform/macos/src/NSImage+MGLAdditions.h index c08fc57bea..b997531c34 100644 --- a/platform/macos/src/NSImage+MGLAdditions.h +++ b/platform/macos/src/NSImage+MGLAdditions.h @@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN - (mbgl::PremultipliedImage) mgl_premultipliedImage; +- (mbgl::UnassociatedImage) mgl_unassociatedImage; + @end NS_ASSUME_NONNULL_END diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm index 6abe53e9ae..bfda98bc39 100644 --- a/platform/macos/src/NSImage+MGLAdditions.mm +++ b/platform/macos/src/NSImage+MGLAdditions.mm @@ -42,15 +42,13 @@ } - (mbgl::PremultipliedImage)mgl_premultipliedImage { - // Create a bitmap image representation from the image, respecting backing - // scale factor and any resizing done on the image at runtime. - // http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431 - [self lockFocus]; - NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, self.size }]; - [self unlockFocus]; - - mbgl::PremultipliedImage cPremultipliedImage({ static_cast<uint32_t>(rep.pixelsWide), static_cast<uint32_t>(rep.pixelsHigh) }); - std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.bytes(), cPremultipliedImage.data.get()); - return cPremultipliedImage; + CGImageRef ref = [self CGImageForProposedRect:nullptr context:nullptr hints:nullptr]; + return MGLPremultipliedImageFromCGImage(ref); } + +- (mbgl::UnassociatedImage)mgl_unassociatedImage { + CGImageRef ref = [self CGImageForProposedRect:nullptr context:nullptr hints:nullptr]; + return MGLUnassociatedImageFromCGImage(ref); +} + @end |