We are trying to build a photo app for a client where large photos are required to be fetched using a web service. These photos will be high resolution JPGs ranging in size (between roughly 5 - 7 mb).
The issue we're facing is how to fetch a batch of photos (say 10-15), store them locally on the app, and allow the user to perform editing tasks on them. What I understood from my team is if we edit the high resolution photos it will crash the app due to memory. This means we will have to reduce the resolution and size of the photo, which is reasonable, but could take a while. What is the best practice to download and reduce the photos so a good user experience is maintained?
To give some background, we are build the app for both Android and IOS. The features expected are typical swipe, pinch, editing with basic editing and advance editing like frames, text overlay, etc.
Not sure this is a UX question so much as about app architecture.
Maybe better suited to StackOverflow or another stack exchange site instead, but I'll try to approach it from a UX angle...
USER EXPECTATIONS
Do your users expect to edit high-res & have control over maintaining maximum quality? Or are they casual users just interested in making funny pix & won't care about loss of quality?
If they expect to have control, you could check disc space or device capability before downloading & offer them a choice of smaller size vs. slower response time.
For example, if they're on an older non-retina/low-pixel-density device, display an alert that editing high-res images might be difficult & offer a smaller version as an alternative.
How will saving/uploading edited versions work? Users might be upset if they overwrite originals w/lower quality versions & weren't given an option to "save as" or set quality level.
USE CASES & DEVICE SPECIFICS
Assumption: A user on a mobile device will only work on 1 image (maybe 2) at a time.
No mobile device is large enough to show multiple high-res images on screen at once anyway. Keep current image in memory; only show thumbnails of others (saved on disc) until requested for editing & then swap; release/reload resources as necessary.
If your users are using older hardware (pre-retina iPhone 3GS or iPad 2 for example), then a 5-7MB image (anything >3000px per side) might be a bit slow, but newer devices take/handle 8-12MP pictures themselves. Should be well within the device's capability to open/edit one at a time.
Are you saying this is not the case?? Can't even open 1 image? Is it being saved to disc first, or opened in-app directly from web service?
Verify adequate storage space either for the whole batch beforehand, or as each image is saved
If device storage is full, cancel remaining downloads & alert user which images are missing
USABILITY & RESPONSIVENESS
Download the images asynchronously to avoid blocking the UI
Create much smaller low-res thumbnails to act as a placeholder for the high-res versions. Download & show thumbnails first to give a sense of progress, but differentiate between an image that's still loading & one that's available for editing (with a progress bar, transparency, etc).
Download in the background (as you might an "in-app purchase") and save to disc.
Download individually & save to shared location. This keeps them organized as a batch of 10-15, but lets the user start working as soon a the 1st image is available. Don't make them wait for all of them.
Could use a separate "downloads" view w/progress bars & let user continue work in another tab/view
Only once the user selects a thumbnail do you need to worry about loading/displaying the large version from disc. You can release thumbnail/loading view from memory & free up resources if necessary while the large image is being edited. Reload only as necessary.
Auto-save to disc in background to prevent loss of work & take opportunity to clean up caches & whatnot.
If working memory is already a concern, you won't have many options for undo/redo. Most image-editing apps manage this ok though, so there's a way.
Related
I am building a flutter ebook app. When the user is reading, the images take quite a while to load since they are over 1 mb in size. This is not a problem for most users with a decent internet connection, but for many others it is. Is it possible to control the quality of the image when being loaded from the internet by controlling how much to download, similar to when you search google images and the images progressively become more vibrant and their resolution increases,but in my case I stop it at a certain quality decided by the user. Thank you.
It sounds like you need to solve this on the server side and have an option in the Flutter app to choose the quality. An example would be to have 5 versions of each image at 5 quality levels and let the user choose the quality level. You can then have a quality parameter in the url you fetch images from. Let's say that the user wants page 12 of a book with a quality level of 2, the url can be something like
"https://mybackend.com/book-title/12/2".
Implementing this solely in Flutter won't solve the internet issue. The app will still download a 1MB image and then you could compress it before showing it but that won't matter.
I am having a problem on how to display user provided images to other users across different devices. For example, I have multiple copies of varying sizes for the same image for my app. These are images I created during development and are part of the app which can support different sized screens. Inside of my app though users can upload a picture of themselves. Obviously now I do not have control of the dimensions of this image. Some users may have new fancy phones which produce very high quality pictures while other users may have not so great phones and produce lower quality images. As well, with user uploaded pictures there is only one image upload. What is the best practice to display these images across various devices. So a user who took a picture on their new iphone 6 will appear nicely on a smaller 3 year old android device as well as a photo taken on a smaller 3 year old android device will appear nicely on an iphone 6?
http://developer.android.com/guide/practices/screens_support.html provides information on how to control images inside of android if I the developer have control of the images, but what if I don't? What if I receive a low quality image from a user, what is the best practice to show it nicely on an ipad for instance?
You can read those guide:
http://developer.android.com/training/displaying-bitmaps/index.html
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap
When receive your image, you can read its size and decide the scale size it base on user device. (But a small image still looks nasty on a big screen).
Beside, I think you can use other download library like Picasso or Glide to support download and decode image.
Hope this helps.
I have a server that communicates with my android app.
In a certain tab of the app it asks for pictures from the server.
The server sends in return all the URLs for the pictures, and the app displays the pictures in the same page.
A problems accures if I have too many pictures, then the app crashes.
I have one solution in mind - to keep two versions for every picture, one with high resolution (Full HD) and another with very low resolution just for preview.
When the app asks for all the pictures, the server will send the URLs for low resolution pics and only if user askes to enlarge a picture then the app will ask the server for the high resolution pics.
What do you think of this solution?
could you reccomend a best practice for this sort of things?
Use a specialized library. They'll handle the complexity behind dealing with remotely loaded images (download, show only when loaded, caching, resizing, etc.).
These come to my mind, investigate and choose the one you like better, but there are others
http://square.github.io/picasso/
https://github.com/nostra13/Android-Universal-Image-Loader
I am building a mobile application that will target iPhone/iPad and Android phones. The application will involve users taking photos and uploading to my server and later on the users will be able to look at those photos on their mobile devices (although not necessarily their own photos so an Android user might be looking at a photo taken with an iPhone).
Which sizes should I save the photos to be able to cover the most use cases? iPads are 1.333 W/H, most mobile phones are 1.5 or 1.333 W/H with some rare 1.666 W/H. Specifically:
iPad: 1024x768, iPad3: 2048x1536, iPhone and some other phones: 960x640, 480x320, 800x480.
To be able to keep it manageable, I need to decide on a few certain image sizes and save the photos in those sizes. I am not really looking for help on the technical side. I can do image scaling on the server side etc. I am looking for recommendations / best practices / lessons learned about image sizes before I go too far into building it.
Which sizes should I save the photos in to cover the most use cases?
Do you recommend any client side scaling before uploading to server to save on transfer time (for example scaling down 2048x1536 iPad photos) or should I always transfer originals?
How should I handle incompatible image sizes (showing a picture taken with an iPad on an Android device for example)? Should I pre-cut those images on my server before sending to client or should I let the client phone handle image resizing?
There is also the issue of UI. There will be other things on the page other than the photo maybe a button or two for navigation. Should I go for something smaller than the full screen size while keeping the same aspect ratio when saving pictures?
I know some of these questions don't have one answer and the answers are relative but I wanted to get some opinions. Thanks.
For Android, I think the best place for you to start would be here, it has a lot of information including standard screen sizes and how to display images while keeping them in the best possible quality.
http://developer.android.com/guide/practices/screens_support.html
I'd also suggest doing as much image manipulation as possible on your server. Images are a pain to work with on Android due to memory constraints and fragmentation. Two phones may store pictures taken the same way with different orientations, and there is no simple way to handle rotations, though it can be done (thankfully, I've yet to encounter a phone that incorrectly records Exif data, but I wouldn't be surprised if they existed...). The more you rely on the phone to do, the more chances you have for error due to manufacturers putting wrappers around and otherwise customizing how it handles media.
As for how to display, ideally if your back end is already doing a bunch of different resizes, you can include your screen density when you request the images and send the best size based on the dev guide. If you want to keep differences to a minimum, at least support med or high density for phones, and extra high density for tablets.
Just my two cents, I'm sure you'll have a lot of opinions. Good luck.
I don't have a full answer for you, but I do have some thoughts...
1) I'd suggest reducing the image sizes before uploading. If I were using your application and I had to upload a 4 meg photo, everytime I wanted to use your application, I'd probably pass. And as we venture forward, we're hitting much better technology in terms of camera phones; Nokia has released a 41 megapixel camera, which I'm guessing will create rather large images. Users having to download a 4-6 MB image is also not a great idea. Just some thoughts from a user point of view.
2) I wouldn't cut the images. You don't necessarily know what parts of the image aren't important, so how would you know where to crop it? Let the phone size the pictures accordingly and rely on the ability to zoom into pictures to see things at a larger size.
3) You could try to make a UI that hides buttons. If you have something really simple (like just going forward or backwards) you could rely on gesture controls (swiping) to move around your application. You can implement sliding drawers and menus that take up space temporarily, when in use, but give you the space back when you want to look at the main content (pictures, in your case). I've typically found that hiding buttons doesn't work well and people seem to want/search for buttons that let them navigate, but the Android gallery works just fine with menu + swiping only, so who really knows.
I’m having a little problem with an app I’m working on. The app shows a gallery that shows between 1 and 70+ pictures (one at a time), all downloaded from the web.
At first I save a low resolution picture and after I finish downloading all low res pictures, I start downloading the high resolution ones and replacing them.
The problem comes when I start downloading the high dpi ones. After some are downloaded I get a memoryOutOfBoundsException (which can be expected).
To solve that kind of problem in android I’ve seen four options:
1.- Using androids Cache Manager.
This is limited to Web Views (So I can’t use them).
2.- Loading the hi res picture every time the user passes thru a picture.
That will make the bad resolution picture appear every time the user changes the picture until the high resolution one (which is loading on the background) gets downloaded and switched. Making the application look bad.
3.- Creating some kind of RAM cache that can hold like 5 pictures and use something like the second method.
In this case, I’ll try to have, in the ram, the 5 hi res pictures nearest to the one that is being showed (either downloaded or being downloaded) so that the app can show hi res pictures for the ones that are near the selected one without having to download them after the user gets to see the low res picture.
4.- Creating a personal Cache Manager
In this case I’ll create a personal cache manager that saves the pictures on the SD card and uses those pictures on the gallery. This also brings one problem, I’ll depend on the user having an SD card on the device. For solving the problem of the files staying on the device after the app is deleted (If the app gets deleted), I’ll just delete all the files on the onDestroy() method of the app (I don’t mind loading them again).
In my opinion, the best option is the fourth. Method, which forces me to depend on the user having an SD card.
Now my questions.
Is there any other way of solving my problem?
Is there another kind of memory on the device than can be used to evade the dependency of the SD card?. Following the question. Is it recommended to use that kind of memory or does using it bring other problems?. (Also, a tutorial about it wold be apreciated.)
Do users usually have SD cards or is the fourth option the worst one?
Thank you in advance.
I would write my own cache manager. If the user can only load pictures to the left and right in the list, I'd keep those three in memory if possible and shift every time the user navigates to a new picture. I'm not sure if that's how your app works, but that's one way of doing it. If you can't predict your user's next choice, maybe have a revolving cache and experiment with how many you can hold in memory at once (not knowing the best, worst and average case of your file sizes, I can't really speak much on that).
You may know this already, but it's always worth mentioning. When you're working with Bitmaps, any time you're done with one...really done with it (such as flushing it from your cache), call it's recycle method. That seems to be the quickest and most widely accepted way of reclaiming that memory for the system.