Git Product home page Git Product logo

haneke's Introduction

Haneke

Version Platform Build Status Join the chat at https://gitter.im/Haneke/Haneke

A lightweight zero-config image cache for iOS written in Objective-C. A Swift version is also available.

Haneke resizes images and caches the result on memory and disk. Everything is done in background, allowing for fast, responsive scrolling. Asking Haneke to load, resize, cache and display an appropriately sized image is as simple as:

[imageView hnk_setImageFromURL:url];

Really.

##Features

  • First-level memory cache using NSCache.
  • Second-level LRU disk cache using the file system.
  • Zero-config UIImageView category to use the cache, optimized for UITableView and UICollectionView cell reuse.
  • Asynchronous and synchronous image retrieval.
  • Background image resizing and file reading.
  • Image decompression.
  • Custom image transformations before and after resizing.
  • Thread-safe.
  • Automatic cache eviction on memory warnings or disk capacity reached.
  • Preloading images from the disk cache into memory on startup.

##Installation

Using CocoaPods:

pod 'Haneke', '~> 1.0'

Alternatively, you can simply add the files from the Haneke directory to your project.

##UIImageView category

Haneke provides convenience methods for UIImageView with optimizations for UITableView and UICollectionView cell reuse. Images will be resized appropriately and cached in a shared cache.

// Setting a remote image
[imageView hnk_setImageFromURL:url];

// Setting a local image
[imageView hnk_setImageFromFile:path];

// Setting an image manually. Requires you to provide a key.
[imageView hnk_setImage:image withKey:key];

The above lines take care of:

  1. If cached, retrieving an appropriately sized image (based on the bounds and contentMode of the UIImageView) from the memory or disk cache. Disk access is performed in background.
  2. If not cached, loading the original image from web/disk/memory and producing an appropriately sized image, both in background. Remote images will be retrieved from the shared NSURLCache if available.
  3. Setting the image and animating the change if appropriate.
  4. Or doing nothing if the UIImageView was reused during any of the above steps.
  5. Caching the resulting image.
  6. If needed, evicting the least recently used images in the cache.

##Cache formats

The cache behavior can be customized by defining cache formats. Each image view has a default format and you can also define your own formats. A format is uniquely identified by its name.

UIImageView format

Each image view has a default format created on demand. The default format is configured as follows:

  • Size matches the bounds of the image view.
  • Images will be scaled based on the contentMode of the the image view.
  • Images can be upscaled if they're smaller than the image view.
  • High compression quality.
  • No preloading.
  • Up to 10MB of disk cache.

Modifying this default format is discouraged. Instead, you can set your own custom format like this:

HNKCacheFormat *format = [HNKCache sharedCache].formats[@"thumbnail"];
if (!format)
{
	format = [[HNKCacheFormat alloc] initWithName:@"thumbnail"];
	format.size = CGSizeMake(320, 240);
	format.scaleMode = HNKScaleModeAspectFill;
	format.compressionQuality = 0.5;
	format.diskCapacity = 1 * 1024 * 1024; // 1MB
	format.preloadPolicy = HNKPreloadPolicyLastSession;
}
imageView.hnk_cacheFormat = format;

To apply the same custom format to various image views you must use the same format instance. The above example does this by initializing the custom format only if it's not already registered in the shared cache. In the last line, the image view category takes care of registering the format in the shared cache if needed.

Disk cache

A format can have disk cache by setting the diskCapacity property with a value greater than 0. Haneke will take care of evicting the least recently used images of the format from the disk cache when the disk capacity is surpassed.

Preload policy

When registering a format, Haneke will load none, some or all images cached on disk into the memory cache based on the preload policy of the format. The available preload policies are:

  • HNKPreloadPolicyNone: No images will be preloaded.
  • HNKPreloadPolicyLastSession: Only images from the last session will be preloaded.
  • HNKPreloadPolicyAll: All images will be preloaded.

If an image of the corresponding format is requested before preloading finishes, Haneke will cancel preloading to give priority to the request. To make the most of this feature it's recommended to register formats on startup.

Preloading only applies to formats that have disk cache.

Pre and post resize blocks

Formats can have blocks that will be called before and after the original image is resized: preResizeBlock and postResizeBlock respectively. Both receive a key and the image up to the corresponding stage. For example:

format.postResizeBlock = ^UIImage* (NSString *key, UIImage *image) {
    UIImage *roundedImage = [image imageByRoundingCorners];
    return roundedImage;
};

These blocks will be called only if the requested image is not found in the cache. They will be executed in background when using the image view category or the asynchronous methods of the cache directly.

##Logging

Haneke provides useful logging that is turned off by default. You can see it in action in the demo.

To turn logging on you must set the preprocessor macro HANEKE_DEBUG to 1. The recommended way to do this is by adding HANEKE_DEBUG=1 to the Preprocessor Macros build setting. If you included Haneke directly, add it to your project target. If you are using CocoaPods, add it to the Pods-Haneke target of the Pods project.

##Requirements

Haneke requires iOS 7.0 or above and ARC.

iOS 6 compatibility can be achieved with very few changes. You can use @shkutkov's fork that adds it by replacing NSURLSession with AFNetworking.

##License

Copyright 2014 Hermes Pique (@hpique)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

haneke's People

Contributors

despinoza avatar dstancioff avatar hpique avatar julianhirt avatar nullproduction avatar pedropalmero avatar ventayol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haneke's Issues

Crash -[HNKNetworkFetcher fetchImageWithSuccess:failure:]_block_invoke (HNKNetworkFetcher.m:95)

The following crash excerpt has been received from devices running iOS 8.0.2 and 8.1.1 with the 1.0.1 release of Haneke. It is happening to external testers so we do not have any further information on what is causing the crash.

0 libsystem_platform.dylib 0x2f93cb34 _platform_memmove + 116
1 libsystem_c.dylib 0x2f8751d9 __memcpy_chk + 14
2 ImageIO 0x22ad9209 _CGImageSourceBindToPlugin + 226
3 ImageIO 0x22ad90dd CGImageSourceGetCount + 90
4 UIKit 0x251332a9 _UIImageRefFromData + 246
5 UIKit 0x2527f4d1 -[UIImage(UIImagePrivate) _initWithData:preserveScale:cache:] + 74
6 UIKit 0x251331ad -[UIImage initWithData:] + 26
7 UIKit 0x2513317d +[UIImage imageWithData:] + 50
8 SHOPPERS 0x00284bed __51-[HNKNetworkFetcher fetchImageWithSuccess:failure:]_block_invoke (HNKNetworkFetcher.m:95)
9 CFNetwork 0x215e9bc7 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 252
10 Foundation 0x2285aae1 NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK + 6
11 Foundation 0x227c5b7d -[NSBlockOperation main] + 146
12 Foundation 0x227b8337 -[__NSOperationInternal _start:] + 772
13 Foundation 0x2285d44b __NSOQSchedule_f + 184
14 libdispatch.dylib 0x2f7e7651 _dispatch_queue_drain + 950
15 libdispatch.dylib 0x2f7e209d _dispatch_queue_invoke + 82
16 libdispatch.dylib 0x2f7e8ba1 _dispatch_root_queue_drain + 318
17 libdispatch.dylib 0x2f7e9cd7 _dispatch_worker_thread3 + 92
18 libsystem_pthread.dylib 0x2f940e31 _pthread_wqthread + 666
19 libsystem_pthread.dylib 0x2f940b84 start_wqthread + 6

Add a cache type parameter to success blocks where applicable

In my app I extend UIImageView with wrapper functions over whatever image related 3rd party libraries I use to make switching between such libraries easy. One example function where I use Haneke's hnk_setImageFromURL is as follows:

func fadeInImageFromURL(imageURL: NSURL, placeholderImage: UIImage?, fallbackImage: UIImage?, completion: (() -> Void)?) {
  var animated = false
  self.hnk_setImageFromURL(
    imageURL,
    placeholder: placeholderImage,
    success: { image in
      UIView.transitionWithView(
        self,
        duration: animated ? 0.2 : 0,
        options: .TransitionCrossDissolve,
        animations: {
          self.image = image
        },
        completion: nil)
      if completion != nil { // I hate that completion?() doesn't work.
        completion!()
      }
    },
    failure: { error in
      if let fallbackImage = fallbackImage {
        self.image = fallbackImage
      }
      if completion != nil {
        completion!()
      }
    })
  animated = true
}

I learned how I can have an animated variable set to true or false based on whether the image was pulled from cache or downloaded by looking at the source code of Haneke. Even so, setting it like this makes me uncomfortable as a change in the library could break it. Therefore I believe there should be at least a boolean variable in the success block indicating if the image was downloaded or not, or better, a variable holding the cache type of the image (e.g.: Holding a value of CacheTypeNone if it was downloaded)

Edit: Yes, I use the Objective-C version of Haneke in my Swift project as it is available via Cocoapods.

The hnk_cacheFormat property cleans cache

Every time you set the hnk_cacheFormat for an imageview, the cache folder associate to the format name is removed. So if you have the same format used for different imageview the cache folder will be removed each time and disk cache will be useless.

Set priority for specific requests

I think it can be useful to be able to specify a priority when setting an image from a URL. This can be particularly handy when setting the HTTPMaximumConnectionsPerHost property of the shared NSURLSession's configuration (to avoid millions of concurrent image requests).

For instance, let's say we have a grid of images (thumbnail URLs) and when tapping on an image, it shows it full screen using a full size URL. In this kind of scenario, I would specifically set a low priority to thumbnail URLs and a high priority to the full size URL (to avoid having an empty screen while waiting for other thumbnails to finish up).

Is that feasible?

Failed to create directory?

Very nice work!
I have an issue when i try to load an image with UIImageView.hnk_setImageFromURL(NSURL)

Failed to create directory with error Error Domain=NSCocoaErrorDomain Code=516 "The operation couldn’t be completed. (Cocoa error 516.)" UserInfo=0x7c032b60 {NSFilePath=/Users/nnnn/Library/Developer/CoreSimulator/Devices/nnnnnn/data/Containers/Data/Application/nnnnnn/Library/Caches/com.hpique.haneke/shared/auto-320x200-aspectfit, NSUnderlyingError=0x7c0339d0 "The operation couldn’t be completed. File exists"}

Any idea?
Many thanks and best regards

Caching fails if url is too long

First of all: Great work! :-)

I have an issue with a rather long image url:

http://sport1.de.feedsportal.com/c/33415/f/587333/e/1/s/3ab5fca1/l/0L0Ssport10Bde0Cmedia0C0Iredaktion20A120Csportarten0I20Cfuball20A1320A140Cwm20A140Csonstiges0I970CBrasilien0IFans0I5x40ITopTeaserBreit0Bjpg/Brasilien_Fans_5x4_TopTeaserBreit.jpg

Caching fails for this url with this exception:

Failed to write to file Error Domain=NSCocoaErrorDomain Code=514 "The operation couldn’t be completed. (Cocoa error 514.)" UserInfo=0x8d299f0 {NSFilePath=/Users/MYUSERNAME/Library/Application Support/iPhone Simulator/7.1/Applications/84EF1482-1AA3-4164-B178-E3D06003CF77/Library/Caches/com.hpique.haneke/shared/auto-148x148-aspectfill/http%3A%2F%2Fsport1.de.feedsportal.com%2Fc%2F33415%2Ff%2F587333%2Fe%2F1%2Fs%2F3ab5fca1%2Fl%2F0L0Ssport10Bde0Cmedia0C0Iredaktion20A120Csportarten0I20Cfuball20A1320A140Cwm20A140Csonstiges0I970CBrasilien0IFans0I5x40ITopTeaserBreit0Bjpg%2FBrasilien_Fans_5x4_TopTeaserBreit.jpg, NSUnderlyingError=0x8de1e10 "The operation couldn’t be completed. File name too long"}

The following change fixed the issue for me:

In UIImageView+Haneke.m i created a md5 hash for the url.absolutestring and used this as key instead of the full path:

NSString *absoluteString = [url.absoluteString MD5];

in method:

  • (void)hnk_setImageFromURL:(NSURL_)url placeholderImage:(UIImage_)placeholderImage success:(void (^)(UIImage *image))successBlock failure:(void (^)(NSError *error))failureBlock;

Best regards and many thanks for the great library!

size looks like a mandatory property on HNKCacheFormat

Hi,

I have same images displayed in two different formats: the first in a list (320x165) and the second in the detail (320x320).

It looks like the current implementation requires a size to be set on HNKCacheFormat.
I don't want to download each images two times and the "auto" behavior doesn't fit my requirements as it will create two folders.

I have made it work using the biggest size (320x320) but I was wondering if there could be side effects doing this.
Do you any advice / solution / bugfix?

Thanks for your help

Removing callback to set image

I have a collection view, with each xib-based cell is being created or re-used as necessary.

Each cell has an imageview which is set with haneke.

The problem is, if I scroll fast, the cells get reused. So if I set an image, and the cell is reused before the the image loads, then the image view will receive multiple images, one after the other.

Is there a way to stop the image request when the cell goes off the screen?

Back in February

Heya. I haven't been able to work in this project lately, mostly due to the holidays and now vacation. I should be back to actively contributing in early February.

If you're comfortable with Haneke, I would greatly appreciate if you can respond to issues and help fellow Haneke users.

Prevent resize?

What's the best way to prevent resizing? I'm loading an image from a URL that has a specified height but an unknown width. I want it to display at exactly that size on the phone.

Thanks.

Getting EXC_BAD_ACCESS

Sometimes I get this error on the line below in UIImageView+Haneke.swift:

    if let context = CGBitmapContextCreate(nil, UInt(pixelSize.width), UInt(pixelSize.height), CGImageGetBitsPerComponent(originalImageRef), 0, colorSpace, bitmapInfo) {

This makes my app crash instantly. Any solutions?

Do you need a success block in the UIImageView category?

I can see the need of a failure block in the UIImageView category (e.g., to retry if a connection failed or to update the UI). However, in which cases would you use a success block?

If yes, when would you need it? After the image is loaded, before setting it, after setting it, or after the animation finishes?

Or maybe it's enough with the format preResizeBlock? For example, you can use that to cache remote images if you can't rely in NSURLCache.

Having multiple HNKCache instances

I have tried to subclass HNKCache to control the folder structure by having a specific name.

Below is my implementation:

@interface FSImageCache : HNKCache

@property (nonatomic, strong, readonly) HNKCacheFormat *mediaFormat;

+ (instancetype)sharedCache;

@end


@implementation FSImageCache

+ (instancetype)sharedCache
{
    static dispatch_once_t onceToken;
    static id cache;
    dispatch_once(&onceToken, ^{
        cache = [[self alloc] initWithName:@"mycustomcache"];
    });
    return cache;
}


#pragma mark -

- (instancetype)initWithName:(NSString *)name
{
    self = [super initWithName:name];
    if (self) {
        HNKCacheFormat *mediaFormat = [[HNKCacheFormat alloc] initWithName:kFSImageCacheMediaCacheName];
        mediaFormat.scaleMode = HNKScaleModeNone; // size is not needed with this option
        mediaFormat.preloadPolicy = HNKPreloadPolicyNone;
        mediaFormat.diskCapacity = 50 * 1024 * 1024; // 50Mo
        [self registerFormat:mediaFormat];
    }
    return self;
}


#pragma mark -

- (HNKCacheFormat *)mediaFormat
{
    return self.formats[kFSImageCacheMediaCacheName];
}

@end

It also allows me to refer to my format as a property and not as a key in a dictionary but that's just for convenience.

The issue I'm facing is that UIImageView when setting hnk_cacheFormat register this format to the shared cache.

- (void)setHnk_cacheFormat:(HNKCacheFormat *)cacheFormat
{
    [HNKCache registerSharedFormat:cacheFormat];
   ...
}

The way you design your library allows us to init a custom cache but the way it's used by UIImageView does not allow multiple cache.

What do you think about this feature?
Is it done on purpose or is it a side effect?

A simple approach would be to set hnk_cache on UIImageView to refer to the custom instance.

Parent format

Allow formats to have a "parent" format. If an image is not available in the cache, Haneke should attempt to create it from the parent format (if any). This should work recursively.

For example, this is useful when you have a "fullsize" format and a "thumbnail" format. "fullsize" would be the "thumbnail" parent.

Cancel the request when the UIImageView is deallocated

The method hnk_cancelImageRequest should be automatically called when the related UIImageView is deallocated. Currently, we have to call it manually.

I believe this is how SDWebImage and AFNetworking work.

Good job, keep it up!

Cheers.

Problem with cocoaPods

I can not upgrade to 0.0.4 via cocoaPods

Invalid `Haneke.podspec` file: Haneke.podspec:3: no .<digit> floating literal anymore; put 0 before dot
  s.version = ‘0.0.4’

It seems the case in the wrong quotes in podspec file

Add convenience to clear the whole cache

Currently there is no convenience method to clear the whole cache. In the meantime:

HNKCache *cache = [[HNKCache sharedCache];
cache.formats enumerateKeysAndObjectsUsingBlock:^(NSString *name, id obj, BOOL *stop) {
    [cache clearFormatNamed:name];
}];

Images are sideways???

I'm using this in a table view and it randomly rotates about half of my images 90 degrees.

Preserve file format

Currently images are stored as JPEG in the disk cache. This is great to reduce the disk cache size but has the drawback of making all cached images opaque and most likely penalises simple PNG images.

Instead, Haneke should preserve the current image format or at least allow the user to set the file format as a cache format property.

Why a frame is mandatory when using Haneke with UIImageView?

Hi Hermes,

I was wondering why your library check by default the bounds of the image view and resize it to its size.

When using constraints (with visual format language), that's a problem cause I want to be able to declare my image view as following:

self.imageView = UIImageView()

Constraints will then set the frame when layout will be applied.

Why not simply not resizing the image downloaded if no bounds? If that case is actually possible with your library, could you show me how with an example please.

Many thanks!
Teddy

Warning in XCode 5.1

UIImageView+Haneke.m:196:24: Implicit conversion from enumeration type 'HNKScaleMode' (aka 'enum HNKScaleMode') to different enumeration type 'UIViewContentMode' (aka 'enum UIViewContentMode')

GIF Support

One really useful thing to add (though maybe some amount of work) would be when fetched data is a gif, it is automatically split to create an animated UIImage, which is then added to the imageview in a way that it starts animating.

(Also: Thank you for the great library!)

Help with the Haneke logo

I launched an illustration contest for the silhouette that will be used in the logo for this project. Which one is your favorite?

The idea is to make an icon from the winning silhouette, perhaps putting the face behind a translucent film (Haneke cache, get it?).

removeAllImages doesn't delete "automatic" cache folders and unregistered formats

Hi,

I was wondering if removeAllImages should do less work and simply delete the cache folder entirely.

I'm facing an issue where some cache format are not "named" (eg. auto) and others are registered later in the lifecycle of the app.

I wanted to do a clean each x launch and was doing it in the didFinishLaunching but it's only deleting formats registered previously.
I found removeAllImages name confusing.

This is breaking change, I think, in the behavior of your library and should be considered carefully.

Also, related to this, how can I delete "auto-..." cache folder ?

Thanks

failed when use AutoLayout

A UIImageView in UITableViewCell when use AutoLayout, it's default cache format created before layoutSubviews. the size is CGSizeZero. So, it failed.

Use concurrent queue for disk access

Use concurrent queue for disk access, with dispatch_barrier_* for write operations.

I did a quick test and didn't measure a performance improvement, which was what I expected. Odd.

hnk_setImageFromURL does not detect image update on the server side

At the moment this method only fetched new image if it is not in cache yet.
When I upload (update) new image to the server, It is not fetched. I would need delete haneke cache for that to occur.
Is there a method to compare some kind of timestamps to not download new image again and again but only if updated?

Bug when trying to use LinkedIn CDN

Any reason why
https://media.licdn.com/mpr/mprx/0_-1nutq8u1AXAgrGjr9vxtBiAPK3YjP-jK-C1tB3luvzmGcLgYzQ8pcvxgOTTYN1A1rNtgrPOKkFF

doesn't work? It works without any issue with UICollectionView. The error I get is

2014-09-21 00:19:00.998 Villow App[1158:124245] https://media.licdn.com/mpr/mprx/0_-1nutq8u1AXAgrGjr9vxtBiAPK3YjP-jK-C1tB3luvzmGcLgYzQ8pcvxgOTTYN1A1rNtgrPOKkFF
2014-09-21 00:19:01.003 Villow App[1158:124245] *** Assertion failure in -[UIImageView hnk_cacheFormat], /Users/sujitnair/iOSApps/Villow App/Pods/Haneke/Haneke/UIImageView+Haneke.m:112
2014-09-21 00:19:01.005 Villow App[1158:124245] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIImageView(Haneke) hnk_cacheFormat]: UImageView size is zero. Set its frame, call sizeToFit or force layout first.'

Thanks,
Sujit

Clearing the cache and get cache size

Hi!@hpique
Thanks for the great source, It works like a charm. Thanks you.
But I have some questions: How do I clear the cache? How to obtain the cache size?
Can you help me?

Jack

Crash +[UIImage(hnk_utils) hnk_decompressedImageWithData:] (HNKCache.m:808)

We have received a few crash reports with the following thread trace. Both times have been on a 5th gen iPod Touch running iOS 7.1.2. Application is still being built with iOS 7.1 SDK

Thread 7 Crashed:
0 libsystem_kernel.dylib 0x381ae1f0 __pthread_kill + 8
1 libsystem_pthread.dylib 0x38218797 pthread_kill + 56
2 libsystem_c.dylib 0x3815efdd abort + 74
3 libsystem_malloc.dylib 0x381dd6f9 szone_error + 314
4 libsystem_malloc.dylib 0x381dd9bf free_tiny_botch + 64
5 CoreFoundation 0x2d3cfa3d CFRelease + 890
6 CoreMedia 0x2d9dda29 CelestialGetModelSpecificName + 298
7 Celestial 0x311a3527 isH1Platform + 20
8 Celestial 0x311a328b FigAspenShouldUseHardwareDecode + 196
9 ImageIO 0x2e2354a1 shouldUseAspenHardwareDecode + 78
10 ImageIO 0x2e200cbb copyImageBlockSetJPEG + 1816
11 ImageIO 0x2e1ea27f ImageProviderCopyImageBlockSetCallback + 540
12 CoreGraphics 0x2d52632d CGImageProviderCopyImageBlockSetWithOptions + 134
13 CoreGraphics 0x2d525fdf img_blocks_create + 376
14 CoreGraphics 0x2d51931d img_data_lock + 1042
15 CoreGraphics 0x2d518705 CGSImageDataLock + 86
16 libRIP.A.dylib 0x2d864e67 ripc_AcquireImage + 96
17 libRIP.A.dylib 0x2d86420d ripc_DrawImage + 586
18 CoreGraphics 0x2d51861b CGContextDelegateDrawImage + 48
19 CoreGraphics 0x2d5184b1 CGContextDrawImage + 282
20 UIKit 0x2fcd04af -[UIImage drawInRect:blendMode:alpha:] + 1444
21 UIKit 0x2fd82b13 -[UIImage drawInRect:] + 44
22 SHOPPERS 0x001dd1cb +UIImage(hnk_utils) hnk_decompressedImageWithData:
23 SHOPPERS 0x001d9e7d __59-[HNKCache retrieveImageForKey:formatName:completionBlock:]_block_invoke129 (HNKCache.m:271)
24 libdispatch.dylib 0x380d3833 _dispatch_call_block_and_release + 8
25 libdispatch.dylib 0x380daad7 _dispatch_root_queue_drain + 220
26 libdispatch.dylib 0x380dad29 _dispatch_worker_thread2 + 54
27 libsystem_pthread.dylib 0x38215bd3 _pthread_wqthread + 296
28 libsystem_pthread.dylib 0x38215a98 start_wqthread + 6

Add transform block

Add transform block to modify the original image. Consider adding transform blocks before and after resizing.

Use custom NSURLSession

Haneke uses [NSURLSession sharedSession] to download images. It would be nice to able to specify which session to use, either with a property or by subclassing.

Thanks to @ronanociosoig for bringing this up.

Always do image decompression

Currently, images are decompressed implicitly when resized for the first time. However, they're not decompressed when loaded from the disk cache or if the format doesn't trigger resizing.

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.