Last updated: September 18, 2024

<span aria-hidden="true" id="build-a-geolocation-image-watermarker-with-transloadit"></span>

# Build a geolocation image watermarker with Transloadit

![Charlie Macnamara](/assets/images/teammates/charlie.jpg?dpl=dpl_6nhQNS5wkVkPZWuKMzXcWrAHNJL5)

**Charlie Macnamara**

Technical Writer & Support Engineer · Scotland · Show bio

While we are proud how versatile our API is, obviously there are always more things, that it cannot do just yet. Fortunately it is easy to integrate it with third-party libraries and APIs.

In this post we're going to demonstrate this in a Node program using the external library *Node Geocoder* to extract geo metadata from images before watermarking this data onto our input image with Transloadit.

![/image/resize Robot](/_next/static/immutable/media/opengraph-image.23j5p9q7nlqdg.png)

<span aria-hidden="true" id="before-we-start"></span>

### Before we start

As previously stated, you will need to use some external tools and an input file. We'll be using the following libraries for this blog:

* [Mdls⁠](https://www.npmjs.com/package/mdls) — A file inspection utility that is only available for Macs (alternative for non-Mac users can be found[here⁠](https://www.npmjs.com/package/file-metadata))
* [Node Geocoder⁠](https://www.npmjs.com/package/node-geocoder) — Based on the information in our found files, it performs geocoding and reverse geocoding
* [Transloadit⁠](https://www.npmjs.com/package/transloadit) — Used to produce our watermarked result

Go ahead and create a new directory to work from and a js file. Once done access your working directory from the console and run the following command:

```bash
yarn add mdls transloadit node-geocoder

```

With setup complete let's get onto the code.

<span aria-hidden="true" id="code"></span>

### Code

First off, we need to import our used libraries. Easy enough.

```javascript
const nodeGeocoder = require('node-geocoder')
const mdls = require('mdls')
const Transloadit = require('transloadit')

```

<span aria-hidden="true" id="info-extraction"></span>

#### Info extraction

Now we can get onto the main body of our code and extract our metadata. While we could import our file from an external vendor and extract our file info using two Assemblies tethered together as shown in this [blog](/blog/2021/04/record-gif.md), that would add to file consumption costs, and well, we've shown that before. However, if you prefer, you are free to use that method.

```javascript
(async () => {
  const metaData = await mdls(`./blog/${process.env.PHOTO}`)
  const lat      = metaData.ItemLatitude
  const lon      = metaData.ItemLongitude

```

Here in our program, we extract our file info using mdls and declare two variables to hold our latitude and longitude values. We use the process.env functionality so we can update our processed file from the command line.

<span aria-hidden="true" id="geo-encoding"></span>

#### Geo encoding

Now we have our latitude and longitude values in place, let's look at how we accomplish our geo encoding.

```javascript
const geoCoder = nodeGeocoder({
  provider: 'openstreetmap',
})
const res = await geoCoder.reverse({ lat, lon })
const [place] = res

const parts = []
if (place.streetNumber) parts.push(place.streetNumber)
if (place.streetName) parts.push(place.streetName)
if (place.city) parts.push(place.city)
if (place.country) parts.push(place.country)

const address = parts.join(', ')

```

Node Geocoder comes equipped with many provider options to choose between several APIs for your geo encoding. We've opted to use OpenStreetMap as it doesn't require any external API keys to be set up; however, take a look at the other available providers as they come with additional configurable options if you wish to expand on this blogs program.

With our options in place, we've initialized an instance of our geo encoder and set a response using the `.reverse` property so we can search with predefined geolocation information. By default, Node Geocoder looks for geo info without that property, but that's not much use to us as we already have the information.

The final part of this snippet takes the extracted geo info and parses it, so it's suitable for our text watermarking. To avoid any `"undefined"`, we only push non-empty values onto the `parts` array, and then join it together with commas.

<span aria-hidden="true" id="encoding-final-result"></span>

#### Encoding final result

With all our geolocation data processed, we can send it off for encoding using the Transloadit API. Head over to your Transloadit console and note both your Auth Key and Secret Key so you can follow along.

```javascript
  const transloadit = new Transloadit({
    authKey   : process.data.env.TRANSLOADIT_AUTH_KEY,
    authSecret: process.data.env.TRANSLOADIT_SECRET_KEY,
  });

  const assemblyStatus = await transloadit.createAssembly({
    waitForCompletion: true,
    files: {
      file1: `./blog/${process.env.PHOTO}`,
    },
    params: {
      steps: {
        ':original': {
          robot: '/upload/handle',
        },
        watermarked: {
          use: ':original',
          robot: '/image/resize',
          result: true,
          text: [
            {
              text: '${fields.address}',
              size: 30,
              font: 'Ubuntu',
              color: '#eeeeee',
              valign: 'bottom',
              align: 'right',
              x_offset: 16,
              y_offset: -10,
            },
          ],
          imagemagick_stack: '{{stacks.imagemagick.recommended_version}}',
        },
      },
      fields: { address: address },
    },
  })
  const resultUrl = assemblyStatus.results.watermarked[0].ssl_url
  console.log(`Here is your result url - ${resultUrl}`)
})().catch((err) => {
  console.log(err)
  process.exit(1)
})

```

From here, we can create our Transloadit API instance. We set up our credentials to pass them in via the command line, then use that instance to create our Assembly.

We use the file parameter to select which file we want to upload. In this case, since we are using the same file we used for processing geolocation info, we recycle the before used method for selecting our file.

Following that, we setup the Steps for our Assembly to use. Apart from our uploading Step, this Assembly only makes use of one Robot,[/image/resize](/docs/robots/image-resize.md). The watermarking setup is simple, and we use theAssembly Variables field functionality for the `text` parameter to pass our previously processed text value. You'll notice that the variable in the fields parameter object stating the address variable is shared by the field value for text. Upon upload, this is what sends our processed geolocation text value to our Transloadit Assembly instance.

It's worth noting we've set `waitForCompletion` to `true`. This is done so that our program knows to wait for a response from Transloadits Assembly before completing the program's cycle.

With our Steps in place, all that remains is to configure a response from ourAssembly. We create a new variable to hold our Assembly result and assign it using our Assemblies results property; if everything goes well, the result will be posted to our console; otherwise, an error message will be displayed.

<span aria-hidden="true" id="results"></span>

### Results

Let's now run our program using the below commands.

```bash
# I got these credentials from: https://transloadit.com/c/my-app/template-credentials
export TRANSLOADIT_AUTH_KEY=********
export TRANSLOADIT_AUTH_SECRET=********
export PHOTO=my_image.HEIC
node geo-watermarker.js

```

Assuming all is well, we're left with the below result in your console which will link to a result similar to the proceeding image:

```plaintext
Here is your result url - YOUR_IMAGE_URL

```

![Geolocation result image](/_next/static/immutable/media/2022-04-geolocation.3cr-calv2kaeu.jpg)

And with that, we've come to an end. We hope you enjoyed this brief walkthrough and learned how to integrate Transloadit into your projects with external tools to achieve impressive results. We'd love to hear your thoughts and suggestions for how to improve this project. If so, please feel free to reach out!

[#image-resize](/blog/tags/image-resize.md)[#letsbuild](/blog/tags/letsbuild.md)[#integrations](/blog/tags/integrations.md)[#node-sdk](/blog/tags/node-sdk.md)[#image-resize-robot](/blog/tags/image-resize-robot.md)

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed · 5 GB included in the free plan

Cancel anytime
