Storing Images as Blob
Tags: javascript, webdev, react, tutorial
Published: 2021-11-11 12:51:13

## Introduction

When images are fetched from API's we simply get the images via URLs and anytime we need to re-use the image, we have to send another fetch request. This can be pretty annoying to keep repeating, as an alternative we can convert the image we get from our URL into a blob consisting of a base64 encoded form which we can use directly in the `src` attribute.

## Goals

In this tutorial, users will learn how to convert images to blob, and store them in a blob format. These images will be fetched from an API and will be displayed in a React App.

## Setting Up

For our React application, we simply have a single page that displays the image received from the API and the image received from the base64 format side-by-side. Pretty cool, 😎 right? Let's dive in.

### Creating our App

We will be using ReactJs for this project. To set up React, we use the following command in the CLI:

``` bash
npx create-react-app images
```

This creates a project folder named `images` which we will be using for our application. You can open this folder in your code editor. Your app structure should be similar to the tree diagram below:

``` bash
┣ 📂public
 ┃ ┣ 📜favicon.ico
 ┃ ┣ 📜index.html
 ┃ ┣ 📜logo192.png
 ┃ ┣ 📜logo512.png
 ┃ ┣ 📜manifest.json
 ┃ ┗ 📜robots.txt
 ┣ 📂src
 ┃ ┣ 📜App.css
 ┃ ┣ 📜App.js
 ┃ ┣ 📜App.test.js
 ┃ ┣ 📜index.css
 ┃ ┣ 📜index.js
 ┃ ┣ 📜logo.svg
 ┃ ┣ 📜reportWebVitals.js
 ┃ ┗ 📜setupTests.js
 ┣ 📜.gitignore
 ┣ 📜package-lock.json
 ┣ 📜package.json
 ┣ 📜README.md
 ┗ 📜yarn.lock
```

We will be making use of the `App.js` file to create our image viewing page and we will add some styles to it in the `App.css` file to give our webpage a better appearance.

## Creating our Image view page

To start, we will clear up most of the boiler-codes that came in our `App.js` file until we have the structure below:

``` js
import "./App.css";
import react from "react";

function App() {
  return (
    <div className="App">
    </div>
  );
}
export default App;

```

For our app, we will need a search bar to get an image that will be displayed. We will start by building this first:

``` js
 <div className="App">
      <input type="search" placeholder="Find Image" />
      <button type="submit">Find</button>
    </div>
```

So here, we have the `search input` tag to search for our image and a button to submit it. To view our app in our browser, we run the `npm start` command in the CLI. Navigate to the `localhost` URL in your browser and you'll get a result similar to the image below:

![Initial appearance](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4nw0qjy9jv49sej5gdi.png)

Looks rather bland right? Let's liven things up with some styles. We can add these styles in the `App.css` file:

``` css
.App {
  text-align: center;
  font-family: monospace;
  padding-top: 8px;
}
input {
  padding: 8px 4px;
  border: 1px solid #e8e8e8;
  margin: 8px;
}
button {
  padding: 8px 15px;
  text-transform: uppercase;
  font-weight: bolder;
  background: rgb(54, 54, 255);
  border: none;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
}
```

Now, in our browser we have the following result:

![Styled search bar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fst4kz8q3qlk43h9ihvp.png)

Looks much better. Next up, we will fetch and display our image from the Unsplash API.

### Creating Unsplash account

[Unsplash API](https://unsplash.com/) provides us with a means to get high quality images from Unsplash which we can put to different uses. To create a user account, navigate to the [Unsplash page](https://unsplash.com/developers) and *click on the "Register as a developer" button*. Fill in your details in the form on the next page and create your user account. *Click on "Create a new application"* and you'll be prompted to accept some "terms and agreements" then finally create a new application. 

![Unsplash new app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv9f91pf5ierkyt6r6rm.png)

finally, we will need the `access credentials` at the bottom of our next page. copy this key and save it in your `App.js` file

``` js
const key = "your access key";
```

For the purpose of this tutorial, we will hard-code our access key. Normally, it's better to store this key in a `.env` file or use a secret management app service like [Doppler](https://doppler.com/) to store your keys.

### Fetching images from Unsplash

Now that we have our access key, we can fetch our image with the Unsplash API. we will be using  `axios` to make our request. We can install `axios` in CLI with the following command

```js
npm install axios
```

With that set up, let’s get our image. We will import this module into our `App.js` file and make our request

```js
...
import axios from "axios";
function App(){
    ...
    const link = "https://api.unsplash.com/search/photos";
  axios
    .get(link, {
      params: {
        client_id: key,
        query: "hp",
      },
    })
    .then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    })
    .then(function () {});
}
```

Above, we have set up our `fetch` request. The `link` variable contains our `URL` to fetch images. Our `axios` request makes use of our `key` in the link's parameter and searches for the query "hp". Once we get a response, the response will be logged in our console. Below is an example of what the response looks like

![API response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pz1ynk0bxpc66bzbtc0r.png)

The response consists of an array of ten images. We are steadily making progress and are almost done with our `image view` page, we just need to get the `URl` for one of the images from our response. First, we will need a variable to store this `URL` and use it in our application.

```js
const [image, setImage] = react.useState("");
```

Then we can set `setImage` to the value of the first `URL` from our response.

```js
... 
query: "hp",
      },
    })
.then(function (response) {
      setImage(response.data.results[0].urls.regular);
...
```

With this, we can create a `img` tag in our app and set the `src` attribute to `image`

```js
<img src={image} alt="" />
```

One more thing, we need to set our search `query` to the input from our `search bar` rather than the "hp" string. To do this, we will create a state variable to contain the value of our input field, then we will place our `fetch request` in a function that will be called when we click the "Find" button.

```js
const [query, setQuery] = react.useState("");
...
<input
        type="search"
        placeholder="Find Image"
        onChange={(e) => {
          setQuery(e.target.value);
        }}
      />
```

Then, for our `Find` button

```js
<button type="submit" onClick={() => handleSubmit()}>
    ...
```

and the `handleSubmit()` function

```js
function handleSubmit() {
    axios
      .get(link, {
        params: {
          client_id: key,
          query: query,
        },
...rest of the code
```

Here, we have added the search `query` from our input field to the `params` for our `fetch` request. now when we click on the "Find" button we have an image based on our search.

![Image from API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fe7hic0413rwvssjoqjc.png)

We can arrange the order the page is displayed through our `App.js` stylesheet.

```css
.App {
...
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
```



## Converting Image to Blob

We have come to the main focus of our application; converting the image from our `URL` to Base64 format. To be able to convert an image to base64 format, first the image has to be of type "blob". Blob is short for "Binary Large Object" and is a data type that can store binary data.

To convert our images to data `URL` we will need to use `File Reader`

```js
...
setImage(response.data.results[0].urls.regular);
getDataBlob(image); 
        async function getDataBlob(url) {
          var res = await fetch(url);
          var blob = await res.blob();
          var base64img = await parseURI(blob);
          console.log(base64img);
        }
async function parseURI(d) {
          var reader = new FileReader();
          reader.readAsDataURL(d);
          return new Promise((res, rej) => {
            reader.onload = (e) => {
              res(e.target.result);
            };
          });
        }
```

Above, we have two `async` functions for our image conversion. The `getDataBlob` function takes in the `URL` from our response, when `res` is returned it converts it to type `blob`. Then, to get the binary data of the image, we use the `FileReader` function. When we check in our console, we see a long string of characters that make up the binary data of our image. To use this data, we will store it in a variable and add it in the `src` attribute of another `img` tag.

```js
  const [newimg, setNewimg] = react.useState("");
```

Then instead of `console.logging` "base64img", we can set this value to `setNewimg`.

```js
setNewimg(base64img);
```

Finally, we can create another `img` tag to use the `src` "newimg"

```js
<img src={image} alt="image 1" />
<img src={newimg} alt="image 2" />
```

Above are our two `img` tags. The former uses the response from our API, while the latter uses the `blob` data URL as their respective sources.

Here is an example of what your output looks like

![Image from bob](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjvbyd5398oh81qmrpqz.png)

## Conclusion

Hurray! we have come to the end of this tutorial. In this tutorial we learned how to fetch images from the Unsplash API, convert them to type blob and get the data URL for use in our application.