WriteToFile/FromFile causes a iOSImage to be rotated?

In an iOS app, I am taking a picture with the camera, then saving it to the documents folder and displaying it. When I display it before quitting the app, everything appears correctly, however saving the picture then reloading it the next time the app is launched causes the picture to be rotated 90 degrees counter clockwise. To save the image I use this, where me.OriginalImage is an iOSImage:

me.originalImage.WriteToFile(xojo.io.SpecialFolder.Documents.Child("Team_" + Globals.CurrentTeam.TeamNumber.ToText),"public.png")
And I later retrieve the image on next launch with this. I have verified that I am getting the correct image name when retrieving, and the image does load, it is just rotated 90 degrees.

dim t as Text = fromJSONDict.Value("Image") self.image = iOSImage.FromFile(xojo.io.SpecialFolder.Documents.Child(t))

Does anyone see anything glaringly wrong with my code, or is there a bug with WriteToFile and FromFile?
Thanks
Jason

I’d try opening it from the Finder - yeah you can get the path to it as it would be in the Finder - and see if that does the same thing.

Makes me almost think that in memory it has some “rotation” property that simply doesn’t get saved or isn’t part of the image data

This is on my phone (you can’t take pictures in the simulator). I know I could access it if it was in the simulator but didn’t think that was possible on a device? Weirdest of all - it seems to save and open sample images correctly in the simulator.

Hmmm cant grab the image off the phone with phone view or something ?
I’d be really curious

I’m betting that there must be a rotation added to the drawing thats not part of the image itself
Something along the lines of

  • (UIImage *)imageWithCGImage:(CGImageRef)imageRef
    scale:(CGFloat)scale
    orientation:(UIImageOrientation)orientation

[quote=173888:@Norman Palardy]Hmmm cant grab the image off the phone with phone view or something ?
I’d be really curious
[/quote]

iPhoto with the phone plugged in can pull the pic off of it.

Photos taken with an iPhone(or other “smartphone”) has an Exif tag(Orientation) telling it what rotation the device was in when taking the photo. Apps reading the image always reads this tag and rotates the image accordingly.
The camera lens does not know what orientation it is in…it has something to do with that.

We had an issue with this while creating an online image editing service.

So is it that the iOSImage doesn’t know about the Exif tag or that the iOSImageView doesn’t respect it? Or something else? This issue will affect my app as well, which is camera/photo “heavy”.

[quote=173869:@Jason King]In an iOS app, I am taking a picture with the camera, then saving it to the documents folder and displaying it. When I display it before quitting the app, everything appears correctly, however saving the picture then reloading it the next time the app is launched causes the picture to be rotated 90 degrees counter clockwise. To save the image I use this, where me.OriginalImage is an iOSImage:

me.originalImage.WriteToFile(xojo.io.SpecialFolder.Documents.Child("Team_" + Globals.CurrentTeam.TeamNumber.ToText),"public.png")
And I later retrieve the image on next launch with this. I have verified that I am getting the correct image name when retrieving, and the image does load, it is just rotated 90 degrees.

dim t as Text = fromJSONDict.Value("Image") self.image = iOSImage.FromFile(xojo.io.SpecialFolder.Documents.Child(t))

Does anyone see anything glaringly wrong with my code, or is there a bug with WriteToFile and FromFile?[/quote]

Wrong EXIF information ?

[quote=173888:@Norman Palardy]Hmmm cant grab the image off the phone with phone view or something ?
I’d be really curious

I’m betting that there must be a rotation added to the drawing thats not part of the image itself
Something along the lines of

  • (UIImage *)imageWithCGImage:(CGImageRef)imageRef
    scale:(CGFloat)scale
    orientation:(UIImageOrientation)orientation[/quote]
    I’ll see if I can get iPhone view. Thanks for that tip. Unfortunately I don’t use any declare like that, I simply load the image from documents then put it in an image view when the user wants to view it.

I thought that it would have to be added to the photo library for iPhoto to be able to see it? Right now I want to try not to do that since there can be lots (maybe even up to 65) of photos taken and I need to be able to easily access them from my documents folder. Plus I don’t want to clutter the user’s photo library.

[quote=173897:@Albin Kiland]Photos taken with an iPhone(or other “smartphone”) has an Exif tag(Orientation) telling it what rotation the device was in when taking the photo. Apps reading the image always reads this tag and rotates the image accordingly.
The camera lens does not know what orientation it is in…it has something to do with that.

We had an issue with this while creating an online image editing service.[/quote]
Interesting should I not be saving as a png to preserve the exit tag? I can use another format available but I’m not sure which one would be best?

I wish I knew. I’m worried that the exif tag is lost when saving. I will have to see if I can save/load using declares instead to see if it helps.

Well you do have your iOSImage extension SaveToCameraRoll / UIImageWriteToSavedPhotosAlbum. You could give that a try instead of saving to the app’s Documents folder?

Right, but I need to be able to retrieve the image at a later time to display it to the user. If it’s in the camera roll they would have to select it again which seems pretty clunky to me. Or are you saying there is a way to get a specific image off of the camera roll?

Ah. Sorry, no I don’t. I didn’t realise that reloading the image within the app was critical. Re-reading your post, I see that I missed that point.

No problem. The app is used for inspecting so it is definitely critical that the image is reloaded. This is the last major hurdle before I can start more serious beta testing.

You should be able to fetch the file from the device Documents folder by enable file share in iTunes. Then look at the EXIF information with the tools listed at https://forum.xojo.com/3881-get-exif-data-from-file.

Since Exif is a relatively simple format http://en.wikipedia.org/wiki/Exchangeable_image_file_format it should not be terribly difficult to correct the issue, if that is indeed where the problem lies. There may even be some things in the iOS toolbox to do so.

Ok thanks I’ll look into that. Unfortunately it “just works” on the simulator. The image is only rotated when deployed to device.

Ok so the issue is that saving as PNG does not preserve the exif data, causing the image to be rotated when it is reloaded. Saving as JPEG instead of PNG solved the issue. Thanks for everyone’s suggestions!

I’ve the same Problem with saving/reading photos to a sqlite database.

Saving as JPEG doesn’t solve the rotation problem in this context !

Writing:
Dim M as MemoryBlock
M = Picture.ToData(“public.jpeg”)
… Insert Into myFotos …

Reading:
… Select * From myFotos …
Picture = iOSImage.FromData(rs.Field(“Foto”).NativeValue)

Result:
All Images are shown rotated.

[quote=193213:@Hans-Jürgen Müller]I’ve the same Problem with saving/reading photos to a sqlite database.

Saving as JPEG doesn’t solve the rotation problem in this context !

Writing:
Dim M as MemoryBlock
M = Picture.ToData(“public.jpeg”)
… Insert Into myFotos …

Reading:
… Select * From myFotos …
Picture = iOSImage.FromData(rs.Field(“Foto”).NativeValue)

Result:
All Images are shown rotated.[/quote]

Yes I had this issue too. I believe the in-built iOSImage.ToData method does not preserve the exif data. @Jason King provided me with a replacement - which I’m sure he won’t mind me sharing - that I rolled into an extension method that I called “ToDataMB”. Note that you will need Jason’s iOSKit for the NSData method.

  Declare function UIImageJPEGRepresentation lib UIKitLib (obj_id as ptr) as ptr
  dim d as new Foundation.NSData(UIImageJPEGRepresentation(image.Handle))
  
  dim mb as MemoryBlock
  mb = d.DataMb
  
  return mb

Thanks Jason - it Works ;-))

@Jason Tait
i’ve on more question. In a different case you mentioned following:

However I need to send it to our web service so I use the Foundation.NSData.DataMB method to get a memory block. That returns a memory block of around 200k to 300k depending on image. The resulting file uploaded to our web service is the exact same size as the memory block.

I checked out the Imagesize that saved to my DB. The size is still around 5MB. How can i compress it to the smaller size ?