Writing Image to ALAssetsLibrary Results in a Different File Hash - ios

I have an application that is downloading images from a server and inserting them into the iPhone's ALAssetsLibrary so that the user can see those images in their saved album. I am trying to do a confirmation by comparing file hashes to ensure the image was downloaded successfully. I have the file hash as the file exists on the server. Once I finish writing the image to the ALAssetsLibrary, I generate a file hash on the client. I'm observing that the file hashes are different but the files appear to be the same. I'm curious as to whether or not the client is altering these images somehow that I may not know about (aspect ratio, scale, metadata, etc). Any guidance, opinions, or advice would be helpful.

The image-data itself is not altered during import into the Assets-Library. However, I observed that JPEG files get about 10KB bigger, after they have been imported into the Assets-Library. The Assets-Library seems to add a JFIF-Metadata-Dictionary to the file, if not already present.

Related

Edit Exif Data in iOS Photos Gallery/ LIbrary without Creating Another Copy

Is there a way to edit/ modify the exif data of the photot that are part of iOS photo library / gallery on the iPhone. Whenever I try to do that, iOS tries to save it as a separate image file. However, I would like to modify the exif data, without creating another copy of the photo. I used libexif as mentioned in the links below, however libexif lets you read and modify the data, but I could not figure out a way to store in the same file.
Gallery APIs in IOS (ALAsset, PhotoKit) do not seem to provide direct access to underlying physical file. They only provide APIs using which the image content can be accessed/ updated or inserted. They do not seem to have apis to modify the exif data. Also, libexif seems to work on the raw filename path. Is there a way to get the raw filename using PhotoKit or ALAsset ?
Am I missing something? Any help or pointers will be deeply appreciated.
How to write or modify EXIF data for an existing image on the filesystem, without loading the image?
Save original image data with modified metadata (no re-encoding) on iOS

Modifying JPEG Metadata without Recompressing Image in iOS

I'm trying to use
CGImageSourceCreateWithData
CGImageDestinationCreateWithData
and then
CGImageDestinationAddImageFromSource
but this discards any thumbnails or other embedded information in the original file. What I want to do is read in the file, alter its metadata, and write it out with the alterations only. But I'll settle for reading everything out of it, and putting it back again. Right now a 1.2MB image file gets converted to a 437kB file with the loss of additional data.
Is there something other than CGImage I can use? Can this even be done with the iOS API?
The problem you face is that the structure of the metadata depends upon the specific JPEG file format you are using.
You need to look at CGImageProperties. You're going to have to make sure the properties for your specific file format get copied as well.
What I was looking for was a read-modify-write operation for image files that allowed changes but otherwise maintained unaltered data. I've determined through research and testing that this is not possible in iOS. The closest mechanism available is CGImage processing, but this only allows you to read selected information from a source image (such as image, thumbnail, properties), and then use some of that information (image, properties) to create a new destination file. There's no way to include a thumbnail in the new destination file, and no way to get around recompressing the image.
As of iOS 7 you can use CGImageDestinationCopyImageSource "to modify EXIF and other image metadata in JPEG, PNG, PSD, and TIFF files without recompressing the image data"
https://developer.apple.com/library/archive/qa/qa1895/_index.html

where to save images in iOS app

In my app user will have a list of items, each item will have a thumbnail,the thumbnails are downloaded from the net, so i want to save the images in the app directory, so that the app won't download thumbnails every time, now i am saving images in NSLibraryDirectory, and there are many directories available like NSDocumentDirectory,NSApplicationSupportDirectory.. those images will be downloaded if they are not present in the NSLibraryDirectory.My question is which directory is the correct place to save these thumbnail images so the user need not download the images every time. Previously i used NSDocumentLibrary but i have read that those will be backed up by iCloud and apple could reject the app for that. So, i have changed to NSLibraryDirectory and everything is working fine. Is it okay to do so. Any better way to store images like that.Thank you
Here is all about this:
https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
I prefer to store thumbnails in temporary directory which system clears automatically. I also wrote class which is responsible for cache files in directory you set.
http://github.com/tomkowz/TSFileCache
it's downloading and retrieve images memory waste. better use: https://github.com/nicklockwood/AsyncImageView

"Fastest way to unzip many files on iOS" or "How else can I download many files quickly into my iOS app"

In my app i want the user to be able to download offline map content.
So I (compressed) moved all my tiles into a zip file. (I used 0 compression)
The structure is like that: {z/x/y.jpg}
+0
+-0
+--0.jpg
+1
+-1
+--0.jpg
+2
+-2
+--1.jpg
So basically there are going to be many many files for zoom level 0-15. (about 120.000 tiles for my test-region).
I am using https://github.com/mattconnolly/ZipArchive now but also tried out https://github.com/soffes/ssziparchive before and both are pretty slow. It takes about 5!! minutes on my iPhone 5S for the files to unzip.
Is there any way I can speed things up? What other possibilities rather than downloading the tiles in one big zip file would there be?
Edit:
How can i download the content of the whole folder quickly to my iPhone without the need of unzipping something?
Any help is appreciated!
JPGs rarely compress at all with zip - they are by definition already compressed. What you should do is create your own binary file format, and put whatever metadata you need into it along with the images (which you should encode with a really low quality number, to get their size down).
When you download those files, you can open then, quickly read them into memory, and extract out data or images as needed.
This will be really fast and have virtually no overhead if your extra data is binary (not text).
PS: I just tripped on a PHP Plist class
If anyone is wondering how I was ending up:
For my use-case (MapTiles) I am using MBTiles now instead of zipped images. It's one big database file and super easy to read if using FMDB. No unpacking whatsoever needed...
Even if I was placing the Images all in one binary file without any compression, the "extracting" still took forever!

Updating iOS application content which include images

I am working on a Vegetable gardening application. Apart from the vegetable name and description I also have vegetable image. Currently, I have all the images in the Supported Files folder in the Xcode project.
But later on I want to update the application dynamically without having the user download a new version. When the user updates the application or downloads new data from the server that data will include the images. Can I store those images in the supporting file folder or somewhere where they can be references by just the name.
RELATED QUESTION:
I will also allow the user to take pictures of their vegetables and then write notes about the vegetables like "just planted", "about to harvest" etc. What is the recommended approach for storing pictures/photos. I can always store them in the user's photo library and then store the reference in the local database and then fetch and display the picture using the reference. The problem with that approach might be that if the user accidentally deletes the picture from the library then it will no longer be displayed in my application.
The only way I see if to store the picture in the app local database as a BLOB.
No you can't put the downloaded images with the others inside the supporting file folder. Also I would suggest you put the images inside an Images or Resources folder instead... If you want to download any data after the app is compiled, then they will not be in the bundle. It is the bundle you are referring to when talking about the Supported Files folder in Xcode. This is read only for your application.
Just to be clear, once compiled, there are no folder structures for your application, these "folders" are just groups in the Xcode project to keep things tidy.
If you download say a zip file containing a set of images, it's up to you to write them to disk after you download them. You should put these images in either the tmp, the cache or the documents directory.
But then you'll have to build your path before loading the images. You won't be able to just provide the name of the file such as:
[UIImage imageNamed:#"something.jpg"];
Because this will look in your bundle. Instead you must do something like this to load your image from the Documents directory for example.
Your challenge is that you will end up in a state where you'll have some images in the Bundle (the ones from when you uploaded your app), and the newer ones in the documents directory. You must them check the bundle first and if there is no image there, check the documents directory.
For user generated data, I suggest also saving the images in the Documents directory, and maintaining an SQLite database of the users data, so you can map an image name to an entry in the database. You don't want to save the images as BLOB because this will inevitably slow down the performance of your queries and add extra unnecessary load on the CPU to convert to UIImage and back.
You don't want to save their images to the gallery for 2 reasons, first this means you'll be saving in 2 places because keeping a reference in your database to an external image is very fragile and you're just asking for trouble, and secondly, once the image isn't under your wing, you don't control it anymore, the user will delete it at some point, if they go back to your app they expect to see it there.

Resources