I have a gallery and detailed view controllers in my application, when a user taps a thumbnail in the gallery I redirect them to the detailed controller and begin to asynchronously download original-sized image, which is 640x640 px and it takes like 5-6 seconds to download. Is there a way to optimize the image download speed?
For example Instagram does this in around 0.2-1.0 second, like incredibly fast. My thinking is that they use some kickass compression on the server side and then unarchive the image they got in the Application. Are there any ways to do something like that?
Thanks in advance.
Solved it, I had to change the image format to .jpeg from .png, the compression rate of 40%, the quality is pretty good and the image size changed to 45kb from 600kb, which increased the speed.
Related
I'm loading images on a list from a server. The UIImageView size is very small (40 x 40), So ideally an image with a size of 40 x 40 or a little larger should be loaded in it. However, the server guy is sending an image of a much larger size (1920 x 1200).
When I diagnosed the view controller memory I noticed that it increases as the image is loading.
So my question is
Will the Kingfisher library download a smaller size version of the image?
Will it abort the image loading if the image size is too big?
Is there any way by which can I specifically achieve the above task.
Kingfisher: https://github.com/onevcat/Kingfisher
Will the Kingfisher library download a smaller size version of the
image?
Nor Kingfisher nor any other library will download a smaller version of an image. The server has to send you a smaller version of it. (different url, or same url with a parameter)
Will it abort the image loading if the image size is too big?
I don't know how the library implements the downloading but unless you are talking about unreasonably big files (way bigger than the resolution you expect (1920x1200)) it will not be aborted. And even then, it probably won't be aborted but instead the app might be killed by the system when displaying super high resolution images (again, way bigger than 1920 x 1200)
Is there any way by which can I specifically achieve the above task.
If you want to display many many images at once and are worried about their sizes, its better to create thumbnails of them.
You can use Kingfisher to
1) first download the image
2) then resize the image
3) then show and cache it if you need
Check this page to see a ton of code snippets for that library.
https://github.com/onevcat/Kingfisher/wiki/Cheat-Sheet
I am making a Chat application for image sending and downloading. I want to do some animation like in WhatsApp. So, how to show the blurred image? My image is downloaded from server. Please help me.
Scale the image down to a very small size like say 8x8 pixels. Send that data to the client. It should not be more than 4 * 8 * 8 = 256 B or 0.25 KB in size, so sending it to the client will not be a problem no matter how slow the client's connection speed is.
Then scale the received 8x8 image to the resolution of the preview box (e.g. 256x256). You shouldn't need to upsample the 8x8 image if the preview box is a UIImageView (see the link below). This downsampling and successive upsampling of an image "blurs" the image.
To understand how you can resample/rescale an image in iOS, check this link. I am not an iOS developer and cannot help you much in performing this task specifically for iOS.
I think that process is done using the server... As I know, there are 2 copies for a single image..
one image with full quality
other image is a thumbnail of original image.. (low size in capacity )
So.. before downloading the original picture client app calls for the URL of the thumbnail & it downloads very quickly since its size is less..
Meanwhile you can use an async function to download original file in the same time..
That is the process...
Hope it will be help for you!!
I'm building a camera application that saves the image data to a single JPEG file in the sandbox. The images average at about 2mb in size.
Problem : I cannot display the images in a photo viewer because having a few images in memory throws memory warnings and makes scrolling through the images very slow.
I cannot split the image into tiles and save them to disk because that's even more expensive than displaying the single image. I tried splitting the image up into tiles upon capture, but on the 5S it took, on average, 5 1/2 seconds to save all the tiles to disk. It will only get worse from there as the app is executed on older devices. This is very bad because what if the user exists the app in the middle of the save? I will have missing tiles and no uncompressed original file to find missing tiles later.
Question : what's the best way to show a full sized image without causing memory issues and keeping the scrolling fast? Tons of camera applications on the App Store do this and the Photos app does this, there has to be a good solution.
Note : I'm currently showing a thumbnail of the image and then loading the full size image from disk in another thread. Once the full size image loading has finished, I present the full size image on the main thread. This removes the memory issues because I only have one full size image in memory at once, with two thumbnails, but still causes lagging on the scrollview because drawing the full size image in the main thread is still pretty expensive.
I would greatly appreciate any input!
you could..
create a down sized thumb nail..
create a smaller image and save that in a different "sandbox" folder.. and read that for browsing.. then after that load the image if the user wants to look at it full size.
One way to deal with this is to tile the image.
You can save the large decompressed image to "disk" as a series of tiles, and as the user pans around pull out only the tiles you need to actually display. You only ever need 1 tile in memory at a time because you draw it to the screen, then throw it out and load the next tile. (You'll probably want to cache the visible tiles in memory, but that's an implementation detail. Even having the whole image as tiles may relieve memory pressure as you don't need one large contiguous block.)
This is how applications like Photoshop deal with this situation.
Second way which I suggest you is to
check the example from Apple for processing large images called PhotoScroller. The images have already been tiled. If you need an example of tiling an image in Cocoa check out cimgf.com
Hope this will helps you.
I have a simple question for anyone who knows the answer to this... I am making a social photo sharing app and I want to save a large enough image in the app so that it can be used in a full screen website app moving forward. Think...Facebook.
I've been playing around with JPEG compression in iOS and also testing sizes and quality with Photoshop CS5. I get really different results with these two. In photoshop, even at high compression, the image is quite clear and retains lots of detail. In iOS, once the compression dips below about 0.5 it looks horrible and blocky. It almost seems like there's a point where the image quality just dips after a certain magic compression number.
With photoshop, I use the "Save for Web" option and with iOS I am using UIImageJPEGRepresentation(image, 0.6). Is there a huge difference in these two? Aren't all JPEGs use the same kind of compression?
I am really not that informed in this world of image processing. Can anyone advice me on what is a good way to have images compressed to a level that preserves quality and stay bandwidth friendly? I want my images to stay about 1280px in length.
Any advice on this or smarter ways to move JPEGS over the network is welcomed. Thank you.
If your app is producing images from an iOS device, you should continue to use UIImageJPEGRepresentation. I don't think it's productive comparing the UIKit JPEG compression to Photoshop's.
I would find a JPEG compression level you're happy with using the available UIKit APIs and go with that. When you're serving up 30+million images a second it might be worth looking at optimisations but until then leave it to UIKit.
I'm receiving a series of JPEGs over the network from a camera (MJPEG). I display the images as I receive them in a UIView. What I'm seeing is that my App is spending 50% of CPU (device and simulator tested) in what appears to me to be the UIView update.
Is there is a less CPU intensive way to do this screen update? Should I process the JPEG in some way before handing it over to UIView?
Receive method:
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(),^{
[cameraView updateVideoImage:image];
});
Update method:
- (void) updateVideoImage:(UIImage*)image {
myUIView.image = image;
...
update: added better screen capture
update2: Is OpenGL going to provide a quicker surface to render to for JPEG? It's not clear to me from Instruments where the time is being spent, render or decode. I'm going to put together a test case as suggested and work from there.
iOS is optimized for PNG images. While JPEG greatly reduces the size of images for transmission, it is a much more complex format, so it does not surprise me that this rendering is taking a lot of time. People have said there is jpeg hardware assist on the device, but I do not know for sure and even if its there it maybe tuned for certain image types.
So - some suggestions. Devise a test where you take one jpeg you have now, and render it to a context, and baseline this time. Take the same image and open it in Preview, then save it with a slightly different quality value to another file, and try that (Preview will strip out unnecessary "junk" from the image, or even convert it first to a png then back to a jpeg. The idea here is to use an image output from Preview, which is going to be as clean an image as you are going to get. Is the image any better?
You can also try using libjpegturbo, and see if it can render your images faster. You can see that library in action in a github project, PhotoScrollerNetwork. You may find that project of use as it decodes the jpegs (using that library) in real time as they are received, and then supports zoomable viewing using CATiledLayers.