I am trying to load a scaled down version of an image without loading original sized image into memory. To reach this goal I was using ImageIO framework. However in this case I face unacceptable loss of quality.
This way I can re-size my image, however original size has to be loaded into memory.
Is there a way to get good quality lower resolution image without loading large image into memory?
Using apple libraries would be preferable, but if there is no other way, third-party library would also be acceptable.
May be Accelerate.framework can help. Use vImageScale_Planar8 to resize image. As I know, this framework supports tiling, probably it will reduce memory required.
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 know this is a stupid problem, but this is my first real app that I have to make, I have no one to ask and I looked up this problem and found no other similar problems.
My app crashes on real devices with no exception. I saw in the simulator that uses too much RAM and after a while I got to the conclusion that the pictures I am using are to blame.
The app is structured in this way: it has 8 viewControllers for different things: for example, it starts with one which lets the user select the avatar with which he/she will play and here I have two pictures, next is a viewController which shows the stats for that avatar and here it is another picture and so on. The problem is that each picture uses 40MB of RAM to be displayed and things add up so the app uses more than 300MB of RAM when the user gets to the gameviewCOntroller where the game is. Because of this, on devices like iPAD 2 or iphone 4 it crashes, but not on iphone 5.
I tried to set the images both from "images.xcassets" and from a ".atlas" folder, but the result is exactly the same. The pictures have a dimension of no more than 1500x1999px, they are in png format.
Also, I saw that if the app were to start directly into the gaveViewController it would use 180MB so the other viewController remain in memory or something like that. Should I "clear" them or something similar?
//-------update-------
This is what I got from Instruments:
Memory is a big deal on mobile devices, there is not a clear answer to you question, but I can give you some advices:
If your images are plain colors or have symmetric axes use resizable images. You can just use one line of pixel multiplied by with or height to cover the entire screen using a small amount of memory
Image compression doens't have effects when the image is decompressed. So if you have a png that is 600kb and you are thinking that converting in a 300kb will lower memory usage is only true for "disk space" when an image is decompressed in memory the size is widthXheightXNumber_of_channelXbit_for_channel
resize images: if are loading a 2000px square image into memory and you show it inside an image view of 800 px square, resize before adding it.You will have just a peak while resizing, but later it will use less memory
If you need to use big images, use tiling techniques such as CATiledLayer
If you don't need an image anymore get rid of it. It's ok to have an array of path to images, but not an array of full uncompressed images
Avoid -imageNamed it caches images and even if Apple says that this cache is released under memory pressure, you don't have a lot of control on it and it could be too late to avoid a crash
Those are general advices, it's up to you if they fit your requirements.
You should definitely follow Andrea's advices.
Additionally you should consider setting the image size to exactly what your need is. You're saying that you've tried to set them from xcassets so you have full control over the images you're loading, which is great (compared to downloading an image that you cannot modify).
I highly suggest you read some documentation on using Asset catalog files. This will allow you to have high-resolution image for bigger screens that also have more memory, and smaller ones for older devices, which is what you want here.
Also, note that 1500x1999px is still a very big size for most mobile devices.
More links about screen-size:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
My app requires that each user has a profile picture of around 140*140px. Right now I am using jpgs, I am wondering if performance wise it will be better to use pngs. I read pngs are good for small UI elements and images, jpg for large images with detail such as photos. Obviously my profile pics are photos but they are small. Would it make much difference switching to png? Thanks
JPEG is best for small file sizes of photos, even for low resolutions.
PNG makes sense when there are many pixels of the exact same color next to each other. This is not the case with photos.
These should be helpful for you.
When to use PNG or JPG in iPhone development?
PNG vs. GIF vs. JPEG vs. SVG - When best to use?
Apple optimizes PNG images that are included in your iPhone app bundle. In fact, the iPhone uses a special encoding in which the color bytes are optimized for the hardware. XCode handles this special encoding for you when you build your project. So, you do see additional benefits to using PNG's on an iPhone other than their size consideration. For this reason it is definitely recommended to use PNG's for any images that appear as part of the interface (in a table view, labels, etc).
As for displaying a full screen image such as a photograph you may still reap benefits with PNG's since they are non-lossy and the visual quality should be better than a JPG not to mention resource usage with decoding the image. You may need to decrease the quality of your JPG's in order to see a real benefit in file size but then you are displaying non-optimal images.
File size is certainly a factor but there are other considerations at play as well when choosing an image format.
I'm using Unity3d (4.3.1) and NGUI for creating an 2d iOS (iPad) app. Also I need to use a lot of full screen images (about 100 images with size 2048x1536), for Gallery for example.
Now I'm using them with GUI type, override for iPhone with max size 2048 and compression quality: normal. And I'm using a UITexture with Unlit/Transparent shader to show them.
However, after about 40 images in the project XCode returns the terminated due to memory error. So the question is, what type of images do I need, and with which preferences to make them work?
I'm using iPad 3 as a test device with XCode 5.1.1. I'll be thankful for any help!
Also I need to use a lot of full screen images (about 100 images with size 2048x1536), for Gallery for example.
I think your 2048x2048 size images use a very huge memory area. Basically, 2048 image use 16MB memory. So, this case need to use about a 1600MB memory! Normal application don't over about 200 MB.
So, I think you need to be reduce using a memory:
Remember that this texture is going to be expand 2048x2048 by unity.( http://www.opengl.org/wiki/NPOT_Texture ) So, if you are going to reduce file size to 1500x1000, your application still use 2048x2048 image. But if you can reduce file size to 1024x1024, do it. 1024 image just use 4 MB memory.
If you can use texture compression. Use it. PVRTC 4 bit ( https://docs.unity3d.com/Documentation/Manual/ReducingFilesize.html ) compression is make file size 1/8 than true color. Also memory size is going to reduce.(maybe reduced to half)
If your application don't display all images, load image dynamically. Use thumb nail.
Good luck:D
If you want to make a gallery-like app to render photos maybe you can try a different approach:
create two large editable textures and fill texels with image data (it must be editable otherwise you will no have access to write directly image data into them).
if you still have memory issues or if you want to use lower memory you can use several smaller textures as tiles. You can render then image parts to each smaller texture. Remember to configurate correctly the texture borders or so not use border texels to avoid wrapping problems.
Best way is to use a smaller texture. In an ipad you will need a magnifying glass to really appreciate the difference between 1024x1024 and larger textures. Remember an ipad screen is smaller (7"~10") than a computer one and with filtering enabled is really hard to tell the difference.
If you still need manager such a large texture for some other reason (zooming or similar) I recommend you one of the following approaches:
split the texture into layers with alpha channel (transparency): usually backgrounds can be rendered with lower resolutions.
split also the texture into blocks: usually most textures have repeating patterns.
use compression.
Always avoid use such large textures if possible.
I'm currently using AVCaptureSessionpresetPhoto to take my pictures and I'm adding filters to them. Problem is that the resolution is so big that I have memory warnings ringing all over the place. The picture is simply way to large to process. It crashes my app every single time. Is there anyway I can specify the resolution to shoot at?
EDIT**
Photography apps like Instagram or the Facebook Camera app for example can do this without any problems. These applications can take pictures at high resolutions, scale them down and process them without any delay. I did a comparison check, the native iOS camera maintains a much higher quality resolution when compared to pictures taken by other applications. The extreme level of quality isn't really needed required for a mobile platform so it seems as if these images are being taken at lower resolution to allow for faster processing and quick upload times. Thus there must be a way to shoot at a lower resolution. If anyone has a solution to this problem, it would greatly be appreciated!
You need to re-size image after capture image using AVCaptureSession and store it's image after resizing.
You found lots of similar question in to StackOverlow i just putting some link bellow that makes help's you.
One More thing As my suggestion that using SDWebImage for Displaying Images asynchronously Becouse App working smoothly. There are also some other way for example(Grand Central Dispatch (GCD) Reference , NSOperationQueue etc) in iOS for asynchronous Tast
Re-size Image:-
How to resize an image in iOS?
UIImage resizing not working properly
How to ReSize Image with Good Quality in iPhone
How to resize the image programmatically in objective-c in iphone