Download #2x and #3x images from server to Tableview - ios

I have a tableview that is populated from images on my server that I download. My question is How would I go about getting different images for the different resolutions for the devices? 6 vs 6plus etc?
Do I write code that is device specific? e.g
if device is equal to 6 load #2x images 'from #2x url'
else if
device is equal to 6 plus load #3x images 'from #3x url'
and so on.
Or is there a more efficient way of going about this?

You've got several options, depending on the back-end technology stack you're connecting to.
Options if you're using a custom server that you've built yourself, or have control over the code:
Add device scale detection into your image service that checks the inbound user-agent for device scale, and serves the appropriate image for that device. This is hands down probably the simplest solution to implement if you manage your own back-end.
Write into your API a url path param that serves the appropriate image scale; you can then use the UIScreen class (UIScreen.mainScreen().scale) to adjust your target URL accordingly, e.g.:
https://api.yourbackend.service/images/{imageid}/#2x.jpg
This is arguably more difficult to implement, but it's also a lot more robust (doesn't rely on potentially changing user-agent strings), and it's a lot cleaner when logging or querying analytics.
You could probably also use something like retina.js to handle this on your back-end, though I can't tell you whether or not it will work heedlessly (haven't tried it).
Options if you're using a CDN image host:
Use their built in HiDPI support (Cloudinary, for example, provides this -- read about it here).
If your CDN doesn't support this, switch to one that does ;)

You are coming at this exactly backwards.
A table view cell's image view is tiny. You are not going to be showing these images at full size anyway. So there is no point whatever downloading larger and larger images only to be displayed at tiny sizes. That's a massive waste of time, bandwidth, and ultimately memory (if you really try to display large images in every cell, you will run out of memory and crash).
If you have a choice of image size to be retrieved from the server, you should be doing just the opposite of what you are suggesting: download a thumbnail of your image suitable for display in the table view. If the thumbnail is twice the size of the image view, it will look good at all resolutions with minimal waste of memory.
If this app is about also fetching the real full-sized image, outside your table view, you can do that later when requested by the user.

Related

Any way to restrict the full resolution image from being served up with Imageprocessor in Umbraco?

I'm working on a photography website in which full resolution photos can be uploaded but full-res should not be able to be displayed/accessed (download of the full res will take place through a token.)
I've tried the "restrictTo" setting but resolutions need to not be reliant on specified dimensions.
Is there a way to have myphoto.jpg by default without a querystring display at for example 700x700 yet still have the full resolution file available through a token download? Pretty much, an image without a querystring is still processed by Imageprocessor but with a default resize rule.
I can request an image with a native width of 5000px by myphoto.jpg?width=1400 but the resulting image is the full 5000px width image, why doesn't the max width 1400px image serve up?
If you are getting the full image back it means something has gone wrong. (You've probably ran out of contiguous memory) so make sure you're in 64bit mode.
maxWidth restricts the resize param to an upper limit only. So does nothing on it's own.
What you are probably looking for is the ValidatingRequest event
http://imageprocessor.org/imageprocessor-web/imageprocessingmodule/#events
I would first set ImageProcessor.Web to intercept all image requests in the processing.config file by changing the interceptAllRequests property. That will ensure you capture any attempts to view the image without a token.
In the event you can cancel the request and also alter/add any querystring parameters to limit your size transparently without showing the querystring to the end user.
I would use a query string for the image.
url?width=1400&height=900&mode=crop&anchor=center
I would also use a lazy load so the page loads faster with small blurry images and then afterwards replaces them all with the full res or querystring for max size you want to display at.
I wrote a script for this.
http://www.codeshare.co.uk/blog/lazy-loading-images/
Also on my site now, when I upload an image, I automatically resize it down to 1080p resolution when it saves. So I can upload a massive image and not have to worry about resizing it first or it taking up too much space on my server.
Here's the code for that too
http://www.codeshare.co.uk/blog/automatically-resize-your-media-images-in-umbraco/

Do i need to return back the image dimensions for ios in json response?

I've built a website that stores images in 4 different sizes on the file system. It keeps the origional file size, medium, thumb, small image and resizes them as they upload.
We then created the web api to allow us to build the ios/android apps.
while building the apis our overseas developer then asked to provide the image dimensions along with the image file name. it took a lot of work regarding calculating the image sizes and saving them to the database.
{ "imagefilename" : "someimage.jpg", "LargeimageHeight" : "1000",
"LargeimageWidth" : "500", "mediumImageHeight" : "500",
"mediumImageWidth" : "250",
"smallImageHeight" : "100", "smallImageWidth" : "60" }
with the amount of image sections we have in the website made it a task and i want to know if this is really nessesary. Im not an ios developer but not really sure as to why the additioanl dimensions of the image need to be saved and or really needed.
i thought the ios has the image feature (#3x) (#2x) (#3x) ??
or do i use 1 specific folder image size for ios ??
does this always happen in the ios world for images that the code needs to know the image dimensions for the best result?
thanks
If your iOS application show images in flow layout (like pinterest style) you must return image dimensions. Otherwise I don't think its nessesary
Do you need the return the image dimensions:
Short answer: no. You can load the image using UIImage, and call image.size.height and image.size.width.
Long answer: maybe, depending on the interface design of your application, and if every image has different dimensions, it might take a performance toll to load the image into memory before being able to get its size (and probably do autolayout and have it render on screen). You might have issues with scrolling speed, but it will depend on the specific design and requirements.
What is the #2x #3x iOS image feature
iPhone and iPad screens come in different pixel densities (non-retina, retina and the retina iPhone 6+ screen). If you have a local image, stored on the phone, it can preload the image with the right scale automatically, by just providing the base name of the image, if you add the right suffix to each asset like name#2x, etc.
Sadly, it doesn't work the same for remote images see this answer. You will have to check yourself for the scale and load the right image, or load one big file, and let it be resized on the device.
You should consider providing dimensions inside your API response.
Think design:
When you scale your app to have many images at once, or when you distribute your app to multiple devices, you may realize the advantage. Your iphone 4 may end up downloading the image (worse, images) intended for iPhone 6S, and so on. If the reverse is true, it's even scary to think about.
How about the device asking for the image it's best suited for?
As for scaling of images, Bram De Geyter is correct - you can render whatever resides on the device, not fetch the correct one from the server. So having your API giving you the right dimensions is the only solution.
I have described the whole image loading from API approach in my blog here.

iOS app crashes because images use too much ram

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

When to use double size images

I was thinking to write some quiz app where questions are represented as images.
My question is, for each quiz question (question.jpg), and thus a jpg file, do I have to create
a double sized question#2x.jpg file?
Is it necessary?
Doing this seems will increase size of my program so I was thinking when/if this is necessary to do?
PS. And in case I have to do it, I will just have to double in size each image manually and add to the project right (both original and double sized image)?
PPS. Just to add more info. The questions are located on the web site, I have to download them and add to my project manually (like resources). On web site there are no different versions of the same image. So, I have whatever is on the web site. Some images I noticed are 800x600 in dimensions but some are also in dimentions 500x400. So after I download these images, how shall I name them? Just with original names? and forget about the #2x extension? What's the best practice?
(if this will help my image view will probably be smth .like 310 in width). Do I have to modify them in size? What to do?
Apple's naming conventions of high resolution images can be found here:
Apple doc naming conventions
If you are developing in the way that you want to support old screen as well as retina screens. You can use xxxx.jpg for old devices as iPhone 3gs and iPad 1, and use xxxx#2x.jpg for retina displays. Where the aspect ratio needs to be the same but the #2x image needs to be twice as big.
In your case "my image view will probably be smth .like 310 in width", then the #2x image needs to be 620px in width and normal revolution 310px.
There is actually no need to have both image sizes in the app as you can use the same image and just scale it(If you really really need to have the old resolution supported).
Even if you add just a #2x, it will scale itself if someone on an old device installs your app. It may become a bit blurry but will still be quite ok.
If you are planning to use a lot of images in your app I suggest using some sort of web service where the user can download content that is to be shown. But that's just me. As the app will quite quickly become very large as images takes up quite a bit of space. Of course this all comes down to how many images you will have.
The drawback of using a web service is that the user much have an internet connection to be able to play. And download your content.(Most quiz apps I know of does use a web service for this.) This is a matter of taste.
If you do need to support normal and #2x here us a method you can use. This method will return the scaled image so you just need the normal one or the #2x one and then scale to the other size. This will at least help you a bit when it comes to getting either your app size down or your clients download time down.
If you are using .jpg's and scaling them upwards you can quite easily get a pixalated image as it is a lossy format. But if that's what you still want to do and maintain aspect ratio, this is one way to do it:
-(UIImage*)resizeImage: (UIImage *)imageToScale withScale:(CGFloat)theScale{
UIImage *image = [UIImage imageWithCGImage:[imageToScale CGImage]
scale:(imageToScale.scale * theScale)
orientation:(imageToScale.imageOrientation)];
return image;
}
Usage
[self resizeImage:[UIImage imageNamed:#"question.jpg"] withScale:0.5];
0.5 would double the size and 2.0 results in an image half the size as the original.
If you want a more complex method to set for instance set a specific target size just say so and I'll edit this answer.

Keep many images in an iOS app

I want to make an iOS app. This app will have over 200 images, each with different sizes (500x500[maybe smaller] and less). What is the best method to keep them, having a smaller app size?
I think about optimizing their sizes for web in photoshop, but still the app will have a big size if I want to keep and a respectful quality.
Any ideas?
Well, I don't know if you can do this for your app, but you can download them from the internet once the user installed your app. This way you can keep the size of the package as small as possible (I assume you talk about non-critical images, that can be obtain afterwards).
UPDATE
Alternatively you can use SVG instead of bitmaps, of course if applicable:
how to render svg file in iphone and ipad

Resources