<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Metadata &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/metadata/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Wed, 02 Oct 2024 04:15:25 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Photos, Metadata and Location on iOS Pictures</title>
		<link>https://blog.xojo.com/2024/10/01/photos-metadata-and-location-on-ios-pictures/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 15:31:02 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[2024r3]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[MobileLocation]]></category>
		<category><![CDATA[MobileMapViewer]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13647</guid>

					<description><![CDATA[Starting with Xojo 2024r3, it is now possible to get image metadata, assign location data (Location Tracking), and to save images directly to a device&#8217;s&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2024r3, it is now possible to get image metadata, assign location data (Location Tracking), and to save images directly to a device&#8217;s photo album in your Xojo iOS apps.</p>



<span id="more-13647"></span>



<h2 class="wp-block-heading">Getting the Image Metadata</h2>



<p>In order to get the metadata from a given image, first retrieve a valid instance from the Picture Class using MobileImagePicker, select Photos or Camera as the image source.</p>



<p>Once we get the Picture instance, for example as the received parameter in the Selected event from the ImagePicker instance, we only need to access its Metadata property. The property will return a Dictionary instance, so we can iterate its entries or convert it to a JSONItem instance for simplicity if all you want to do is store the information. For example, we can use the following fragment of code in the Selected event of the ImagePicker instance:</p>



<pre class="wp-block-code"><code>Var js As JSONItem
Try
  js = New JSONItem(pic.Metadata)
  MessageBox(js.ToString)
Catch e As JSONException

End Try
</code></pre>



<p>Assuming that &#8220;pic&#8221; is the name of the received parameter that points to the user selected (or captured) image, the previous fragment of code will show a dialog with the image metadata.</p>



<h2 class="wp-block-heading">Getting the Image Location…&nbsp;and Putting it On the Map!</h2>



<p>An interesting action could be reading the location data of the selected image and adding an entry on a MobileMapViewer instance. So, for example, again in the Selected event of an ImagePicker instance, we could add the following snippet of code:</p>



<pre class="wp-block-code"><code>If pic &lt;&gt; Nil Then
  ImageViewer.Image = pic
  
  // The metadata is retrieved as a Dictionary, so let's get the
  // metadata from the selected picture
  metadata  = pic.Metadata
  
  If metadata &lt;&gt; Nil Then
    Var jlocation As Dictionary = metadata.Lookup("Location", Nil)
    
    // Getting the Location information (also as Dictionary)
    If jlocation &lt;&gt; Nil Then
      
      // And assigning the Latitude and Longitude
      // values to the properties
      latitude  = jlocation.Value("Latitude").DoubleValue
      longitude = jlocation.Value("Longitude").DoubleValue
      
      // Then, we will show the Picture location on the Map
      Timer.CallLater(100, AddressOf Showlocation)
    End If
    
  End If
  
End If</code></pre>



<p>Latitude and Longitude are Double type properties that have been added to the Screen containing the ImagePicker instance, also added is an ImageViewer instance responsible for displaying the selected image preview, and a MapViewer instance on which the &#8220;pin&#8221; corresponding to the location of the image will be added.</p>



<p>As you can see, the shared method CallLater of the Timer class is used to invoke the ShowLocation method. This method will be responsible for displaying the actual pin on the map:</p>



<pre class="wp-block-code"><code>Private Sub Showlocation()
  // Let's create a new Location instance from the stored
  // latitude and longitude values in order to add it
  // to the Mapviewer…
  
  Var maplocation As New MapLocation(latitude, longitude)
  MapViewer1.AddLocation(maplocation)
  
  // …and let's make sure the metadata is updated
  // to the viewed image
  ImageViewer.Image.Metadata = metadata
End Sub</code></pre>



<p>The following screenshot shows the outcome of executing the previous code:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img fetchpriority="high" decoding="async" width="828" height="1792" src="https://blog.xojo.com/wp-content/uploads/2024/09/PicturePicker.jpg" alt="" class="wp-image-13648" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/PicturePicker.jpg 828w, https://blog.xojo.com/wp-content/uploads/2024/09/PicturePicker-139x300.jpg 139w, https://blog.xojo.com/wp-content/uploads/2024/09/PicturePicker-473x1024.jpg 473w, https://blog.xojo.com/wp-content/uploads/2024/09/PicturePicker-768x1662.jpg 768w, https://blog.xojo.com/wp-content/uploads/2024/09/PicturePicker-710x1536.jpg 710w" sizes="(max-width: 828px) 100vw, 828px" /></figure>
</div>


<p>Of course, you&#8217;ll need to enable the Maps entitlement in the Build Settings &gt; iOS &gt; Capabilities inspector.</p>



<h2 class="wp-block-heading">Setting the Location in a Picture</h2>



<p>Just as we can get the location out of an image, we can also modify it… or set a location to those photographs that we get through the ImagePicker using the Camera source. Assigning a location is very simple:</p>



<ul class="wp-block-list">
<li>Add an instance of MobileLocation to the project (for example the screen where we manage image capture).</li>



<li>Add the Latitude and Longitude properties of type Double as two new properties on the same screen.</li>



<li>In the LocationChanged event of the MobilLocation instance assign the values received in the Latitude and Longitude parameters to the properties created previously:</li>
</ul>



<pre class="wp-block-code xojo"><code>Self.Latitude = Latitude
Self.Longitude = Longitude</code></pre>



<ul class="wp-block-list">
<li>Then, in the Selected event of the ImagePicker instance, use the following snippet of code:</li>
</ul>



<pre class="wp-block-code"><code>Var d As New Dictionary
d.Value("Latitude") = Self.Latitude
d.Value("Longitude") = Self.Longitude

Var Location As New Dictionary
Location.Value("Location") = d

pic.Metadata = Location</code></pre>



<h2 class="wp-block-heading">Saving Pictures to Photos</h2>



<p>Until now, MobileSharingPanel was probably the go-to option when it came to saving any of the images generated in your iOS Xojo app or images captured with the camera using the ImagePicker. Starting with Xojo 2024r3, you can also use the SaveToPhotos method of the Picture class, which will take care of saving the image while preserving the associated metadata.</p>



<p>So, for example, you will only have to add the following line of code at the end of the previous block so that the captured image is saved with the location:</p>



<pre class="wp-block-code xojo"><code>pic.SaveToPhotos(Picture.Formats.PNG)</code></pre>



<p>However, when using this method on images in your iOS app, make sure to enable the Photos Access capability in the Build Settings &gt; iOS &gt; Capabilities Inspector Panel.</p>



<h2 class="wp-block-heading">Wrapping-Up</h2>



<p>As you have seen, it&#8217;s now really easy to get metadata from Picture instances in your Xojo iOS apps, as well as leverage Location information and assign location information to any of existing or new images. Plus, you no longer need to resort to <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilesharingpanel.html#mobilesharingpanel">MobileSharingPanel</a> if all you want is your iOS app to save images to the Photos app album on the iOS device.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tip: Get Metadata for an Image on macOS</title>
		<link>https://blog.xojo.com/2021/09/03/tip-get-metadata-for-an-image-on-macos/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Fri, 03 Sep 2021 12:00:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9067</guid>

					<description><![CDATA[Getting the metadata from an image file on macOS is quite easy using Declares. Learn How in this Xojo blog post.]]></description>
										<content:encoded><![CDATA[<p>Getting the metadata from an image file on macOS is quite easy using <code>Declares</code>. Continue reading and I&#8217;ll show you how!<span id="more-9067"></span></p>
<p>Create a new Desktop project in the <strong>Xojo IDE</strong> and add a new <code>Module</code> to it (for example, named <code>External</code>).</p>
<p>Next, add a new method to it using the following data in the associated Inspector Panel:</p>
<ul>
<li><strong>Method Name:</strong> MetadataForImageFile</li>
<li><strong>Parameters:</strong> source As FolderItem</li>
<li><strong>Return Type:</strong> String</li>
<li><strong>Scope:</strong> Global</li>
</ul>
<p>Now add the following snippet of code to the Code Editor for the just added method:</p>
<pre>Var desc As String

#If TargetMacOS
  
  // Declares against the "Foundation" framework
  Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As Ptr
  Declare Function FileURLWithPath Lib "Foundation" Selector "fileURLWithPath:" (obj As Ptr, path As CFStringRef) As Ptr
  Declare Function Description Lib "Foundation" Selector "description" (dict As Ptr) As CFStringRef
  
  // Declares against the "ImageIO" framework
  Declare Function CGImageSourceCreateWithURL Lib "ImageIO" (path As Ptr, options As Ptr) As Ptr
  Declare Function CGImageSourceCopyPropertiesAtIndex Lib "ImageIO" (imageSource As Ptr, index As Integer, options As Ptr) As Ptr
  
  If source &lt;&gt; Nil Then
    
    // Getting a Reference to the NSURL class
    Var nsurl As Ptr = NSClassFromString("NSURL")
    
    // Getting a reference to a NSURL object created from the given Path
    // for the source file
    Var filePath As Ptr = FileURLWithPath(nsurl, source.NativePath)
    
    // Getting a reference to the image object created from the 
    // given NSURL object
    Var imageRef As Ptr = CGImageSourceCreateWithURL(filePath, Nil)
    
    // Getting an NSDictionary containing the Metadata for the image
    Var dict As Ptr = CGImageSourceCopyPropertiesAtIndex(imageRef, 0, Nil)
    
    // Getting the contents of the NSDictionary instance as a String
    // This will contain the metadata for the image file!
    desc = Description(dict)
    
  End If
  
#EndIf

Return desc</pre>
<p>Now you can call this method from your code in order to get a String containing the metadata information for the FolderItem passed to it as parameter.</p>
<p><img decoding="async" class="alignnone size-large wp-image-9068" src="https://blog.xojo.com/wp-content/uploads/2021/08/ImageMetadata-977x1024.png" alt="" width="977" height="1024" srcset="https://blog.xojo.com/wp-content/uploads/2021/08/ImageMetadata-977x1024.png 977w, https://blog.xojo.com/wp-content/uploads/2021/08/ImageMetadata-286x300.png 286w, https://blog.xojo.com/wp-content/uploads/2021/08/ImageMetadata-768x805.png 768w, https://blog.xojo.com/wp-content/uploads/2021/08/ImageMetadata-1466x1536.png 1466w, https://blog.xojo.com/wp-content/uploads/2021/08/ImageMetadata.png 1748w" sizes="(max-width: 977px) 100vw, 977px" /></p>
<p>You can find more information from Apple about the <strong>ImageIO Framework</strong> <a href="https://developer.apple.com/documentation/imageio?language=objc">here</a>. Ask me questions on Twitter <a href="https://twitter.com/xojoes">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary">Xojo Forum</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
