How to upload a base64 or binary image?

Hi there,
i have a problem with uploading a new image with the CMA.

The image comes through an input file via a form, so i only have it as binary or base64 data string.
I thried it with space.createAsset(), but this doesn’t work, because he wants an url path.

Older solutions, that i found, are deprecated like space.createUpload()

I’m not able to find any more solutions. :frowning:

So, is there any possibility to upload a new image via CMA with base64 or binary?

Thanks
Alex

Hi @alexander.blache ,

I believe you are following this tutorial:

The createUpload function should be now on the environment, not on the space:

Hi @Alma
i tryed several approaches by now, and yes i use the environment.createUpload().
I also tryed to send the image data in different formates. Stream Text and ArrayBuffer.

In my desperation, i also send it as a base64, wrote it to disc and send the path to my temporary file, nothing.

Every time its the same, the asset will be created in contentful, but the image isn’t there

After the upload part, i receive this, so i assume, that the upload was correct, after that, i create the createAsset() statement:

Upload {
sys: {
id: ‘5w5SsjVNiyLdOMh6m5B1jt’,
createdAt: ‘2021-05-18T12:46:30.000Z’,
expiresAt: ‘2021-05-20T00:00:00.000Z’,
createdBy: { sys: [Object] },
type: ‘Upload’,
space: { sys: [Object] }
}
}

My code:
async function newImage(json, image) {
try {
let type = json.type
let name = json.title

    const upload = await imageClient.getSpace(config.space)
    .then((space) => space.getEnvironment('master'))
    .then((env) => env.createUpload({file: image}))
    .then((upload) => {
        return upload
    })

    console.log("Upload ", upload)

    const asset = await managementClient.getSpace(config.space)
    .then((space) => space.getEnvironment('master'))
    .then((env) => {
        env.createAsset({
            fields: {
                title: {
                    'en-US': name
                },
                file: {
                    'en-US': {
                        fileName: name,
                        contentType: type,
                        uploadFrom: {
                            sys: {
                                type: 'Link',
                                linkType: 'Upload',
                                id: upload.sys.id
                            }
                        }
                    }
                }
            }
        })
        .then((asset) => {
            return asset.processForAllLocales({processingCheckWait: 2000})
        })
        .then((asset) => {
            return asset.publish()
        })
        .then ((asset) => {
            return asset
        })
    })
    .catch(console.error)
} catch (err) {
    console.log("ERROR: ", err);
}

}

Thats the result

Could you provide further aid?

Greetings Alex

Hi @alexander.blache ,

I tried to reproduce the issue, and I was able to identify that possibly some informations were missing in the method newImage. Here my code for reference:

async function newImage(json, image) {
  try {
    let type = json.type
    let name = json.title

    const upload = await managementClient.getSpace(config.space)
      .then((space) => space.getEnvironment('master'))
      .then((env) => env.createUpload(
        {
          file: image
        })
      )
      .then((upload) => {
        return upload
      })

    console.log("Upload ", upload)

    const asset = await managementClient.getSpace(config.space)
      .then((space) => space.getEnvironment('master'))
      .then((env) => {
        env.createAsset({
          fields: {
            title: {
              'en-US': name
            },
            file: {
              'en-US': {
                fileName: name,
                contentType: type,
                uploadFrom: {
                  sys: {
                    type: 'Link',
                    linkType: 'Upload',
                    id: upload.sys.id
                  }
                }
              }
            }
          }
        })
          .then((asset) => {
            return asset.processForAllLocales({processingCheckWait: 2000})
          })
          .then((asset) => {
            return asset.publish()
          })
          .then((asset) => {
            return asset
          })
      })
      .catch(console.error)
  } catch (err) {
    console.log("ERROR: ", err);
  }
}

Be aware to create a managementClient like the following (I assume from the previous code, you are using a config array. In this case token is the CMA token):

const contentful = require('contentful-management')

const managementClient = contentful.createClient({
  accessToken: config.token
})

And, as said before, the Json Data should look like this, where both (mime) type and title are set

let jsonData = {
  'type': 'image/png',
  'title': 'my-cute-cat.png'
}

Once you have all in place, you could pass a file to it in two ways:

const fs = require('fs')

let fileName = './myfile.png'
let imageResource = fs.readFileSync(fileName)
let imageStream = fs.createReadStream(fileName)

newImage(jsonData, imageResource)
// Alternatively
// newImage(jsonData, imageStream)

And, if you need to use a base64 image, before ‘opening’ the file, you would need to save it temporarily (ie: local file name ./image.png):

let base64String = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA4QAAAH0BAMAAACX3f7gAAAAGFBMVEU5q+DR0dToWGb/2GCVl5xbYGcqMDn///80UuYpAAAPNUlEQVR4XuzRMQ2AUAwFwOKAN32dnWqflQQFDXcWrmY5FCpEIQoVohCFKFSIQhSiUCEKUYhChShEIQoVohCFKFSIQhSiUCEKUYhChShEIQoVohCFKFSIQhSiUCEKUYhChShEIQoVohCFKFSIQhSiUCEKUYhChT+gEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChV2kruSnFlIYaderm2LClMfmT0UPuzb0W7CIBSH8eOVtzRx62u48AKaOPsCrr02sXg7UnWvv7gsOzpimS2Hgfl/D2AkP6FAIwPmhghCBswYEYSKnHJ6JoLQkqfEDUFoydsEAEkSsmCehiBkwTwNQciCeRqCkAVzNQShK5jjvhSEijI1BCELChgiu/qqlCdUdG8f/tCsNt9V0oSWuFBbGmRfzU+tNKEiLtBSimxtLqrECFkw7FKK7NpcthUltMSFWkrRtaDZiRIq4gItpehgrmslCd+Jgk9DVMckpMFNbwGgo4lIqGh4twBQHZHQEklOQ0xCeUJFXKgdDVpHJLREwachsiYioaJxeQCwjoqfCzuih5qGM34vEKHZ27mlZx0deDtjX88fvil9hIq4BzgbPvEvPkKHm9efxq0Z+DhtxQkpyRuRJurBYefaOrUhxkK+dTT/PekzP3gixFC/F+6TK1gNH0s/4QuNbprkVj7unqXpexRulvwXzUFj6SXs5jS6SZJXImXMOW/2zvcY/57Q8Fj6CPWDEZpECB3BtAkpScLqPwktC+6CjsUl7PRCgBCEByZshAm1CCEIj0xYyhJ2WpMAIQhPntNgRMJJcQawhbrrYAhCtt0KE2om9P0nuxg0C0G4j0bon1tWeQlB6J7KG1nCTmu9+PthT91PCMJKllAzYY8gp1IkBOHcL8gVHm4Quvd8ooSdQ+jdY6osCEHIgm5q0JsK/ziK2Wq1LMYTfrJ3N72N20AYgC/9AeutIZ7rFuh1tymwZxe2eDZgS2cBpHxmI1l/vw2yWIZ6NTOkokhK1jzGDD3ko6FofUYRuu2xeFK+HPbvnPDhqXxlBbEkVu/c4VI/Dxft6I7Fj9MygEK2aaEyEFLf5qEtIFLh2YNaKeFD4sTokDDy/rr6TCAea6iEjdjzwF2XVtOE+81zUcQ9m2QbzSVo2R0xNiSsNt+LJwzD+NH4U6GS318rQxLCPDo4k/K5/ylBvAmHy+6ZOr7TxKnP0oPSlWssGrcX/EK8J1D58IAbCT2zJwyKCQ5/n9hrZVQi4d+pu7b4+lvsoCiI/WuCo40uh8oCoQVB1vAWHBlrYHsQCGuNhF4th/mVuVZGJnz4Xvh5Ub4NihHEYhQKCoa3oCM5Dz4kVML1bVyi5i/lXd/CKonQEIQ2UCnZa2VSCb+kri/p+pg9aAizlmDo0cphAy0RVowgJoX/22B4ViKsgdA7NBATca0MTYjzKKYhUAhpqFhBmUdOC08x2KiVCA2GhFXwfLseDu8kESqCsOy6FmIilrGphF9SL0f7BPW5gJBHzgo71JAhkvYkEFpoCUuJzCVBrgVCTRBeWUIkkwkffEk90uIi6mfMFi9nRV0NEFqqUSUQ4gaDzAoIrwS5WSOhX5T+oroEQxTkdDCgnK2EhA3jLRO6misVEFatGNryhGj4rYsrTnpQdx41WkwxSFiT5BIhhoRF9QlNwYa2POGjB/xxzunwAISk4ScuB2UdeUw1ENKljCB0chueUNBeDyGWbqKSS4TyYJkEQhNBmAkuNp6wXDHhtwn0ZJ2KY8a4kRCLkglFGB1NaNdB+PBWhLJOCRMbIR1PWIm/C1u5jWjCWo36XTgL4USCThqAqDG1CYRGPDqTy7kVT3gddXRmBsLJkrB9zTwKgRcpeUFlvYuA0dGEJuIYKdJOTPi43DyqIVMp6wTCkia0AzlvD5uu2xwKyK04wlqln6moZiCccB6Fs4RuW/SCxzHdbI8w9gTh5QLcSMic4NgPnkwxBKG9gIgmCU9EzEa9F0LUOatwtPRQpp4Gz6hrTwgtuhy4A0K7Cc7aA8CQ4SCh3Q9Edu0T7qmz9if/9xkIp5pHM+KIaAFjDVnRQGoBodWDhzxVnxB+5YAgtKI9YZg9sMmYPqEONQqY4acinGc1U+DhY++jB6xOxFgbT9gDQEPNEt6CDYPacZeeEON3QbdWQDjXrlD3csEMjKkhl0IDhCeibskS5gEKlaAVEioik9WHJmxBx+eNVaEUMjt+dWep6bFiCYvQmvjMEFM5EfPHJcxAh59sDf3vVyDUVHIZjtBB/gyOqwVCRbVSLk84z69CGzPZavqjCnatZMJbIKQnS3ImVZ5Q2G1WixO6eVYz14jj4FbaBIowLZnsQkLc85ZcwBr2eNQWY5YiZH9TqOlXM2STLZMWLXO8UdHcmiHMwhahEYLQ0l2zqyRMpEpOMGJMtTTJFkyDN54QkQwbTBkSXiFffzrCKmZ/qfBDkrBivqxkCAs2pNabhYSaxq4/MmHL7ndwIc+maBkSlkzGXhlCPiSvVoWEXN/UCgm/vl4P5zaqsJnahC4Fl7EFS4jQ5wOWox/YgNBwkemlCX+d5QipiljylOynVUjIzcgVRehZxGKE/YBbnnDen4W2iyDUbF8MTLpvSmh7UwCUn43QxCx5FN9E/H7TTEiIo480H5MQV38yoZDIUoO3GMK2ji2wu7sTEqXlJ9uMILzOS6juhNcIQiMsamE4xhDeJiPMfec+MGE9K2H7hoTdnbAcS9iOIbRTECqB8J6FOKYVQ3gnvBPeCe+Ed8L7vvDd/y6cdUVq39WK1CYR3gnbd0HoVn2MdPzRmXkJ7ZKEzQoJ7ehjpBMTNrGE1Z0Qzhe++kzFrIRn9XaEcr/bRMIlz9rL5wsnJnTRr99ZkjB7X9fORJ+1n5pQr4VQY9trJKwSl63Y0esrCXGLWZTQcYHUa7+OVF7zyFewpRPiCbCFCOXLvpr1EDoIZarrSNMJsUWzLGHBXNWcSjjPPRUV4mGisVf0jyasuVXy9IRlIiEGkq+FUL6zCW8wke+pGE+IS6xlCNGphA13yZvT0u8vbOJudTGvIFTDLuZtCK9xhBkZSDYF4dep1zMYp7vscflV0bpVMqH31tT+eULCG4AgIbnDU4C+ynvtcVegIGKryH3CdRwh5kXBpuFm/2pCKxLi9gkP3liYEONHnwwe94F9aaArSYQ5UBFrhXD49DjCFlpFQnrzVvD3VxOqyXaGaOh1NJ480NRbD7pxhEh1g4jCBDCvJjQioWfBf8lHED7O9hQ9o8O3ihhMNquH+2KSCKn1An6dwilMJxP2mz2JhNg/EFzpM9jq80a9fASW9jDBQ7LwqVxVOuGNeIMX9aYtd/TeaYTQ0/N+s1ESYQaBQK+XJMSOeqML+aQB3//tEXqSTNiG33q57H1IqOv8sxD1GMIOOnoSCNv+wJwPfmhW9DDLdprnftounbAhBhVCulwOwfMUTSqhp0rZ7BzT32UfKSvHCaMlE1ZphNRXq7ih04mEnjRp8i8mJJx3JsUIM7kjqYQheAifS4RmDCF2wgqE2RsTqlmekF9XbB1vkkjI5kUrj1saIdVRRRMK3V7PE/Ll6cJ4GgE6nfBGpZdIWI0gdCmEUhzretVIK+aXnBdqFGFDEWZi1qcRUkmvBcLszQj/2u0S03AzOg1t9KInnRC/2cauBccQZsmEzWSErg/4VOIJt0/V/1Dj0rCMyQudTAitwgfTZ2EjEsZv3XkiYQeCT+X3SMHP3+v/NiYNrYrIC9ONJGwoQjftvhBQeUJ56z5lqYQo+FT+jBWUDBs2v+RUVSMJcVAtnNChN6x0wjaR0PtCmLdoQtwZ7l6USEHZPGPyS07VU5dKiEc5MZ+n/GlPgajImJG+TSaEJIxNQ7d7WRRVC33wmfkcMw6bjiLscorQyYKdiyQsqT4oMeYu52/nQEI1TOggCWPT8J8dmMuG8lsikFkmxNeM4xdXAM5mvQ+CnVo0BcLH7NVxO3M9siJsEwk7SEIgYZMQzeVIkSGXmW9kWlAv+28Cw1LeZOozREQ8uhQSA19CIseMYVjlzfAtGEYi3AEJX/r1FW2IebiXJhWs1AQ9If9fUV+s5LQ/Q6IR+eN6saBhiTHLhlYH8FVve6kowkdMQlxkYvkX68cb7tHgiDlIKGkq1dHXHWsCfittMq5ApBAYfQ8eA2OWDa0Ov1qFjViVSrhTwjTKpi0C4fuPYFCxEnpY4H/5qq5zv2m3PcIHPkO5qBpoEDpk9/htl6dyVhgzGTZeXdAUHtQ3ojuKsIN5NCYNP+8SyZ9HEgyA6LnYQzdh4dAhqrnL9hnooMSa6YQ7LSVh2gJoc/i/7Dlo93z1gT3PNJ7b5++rL4fNf+zXMWrFMBBF0TVI+eDaQyD9zw68o7GKt/1AGhcKVuGA9ODeLRw0M5JRPWHr52j/rsaCsYsmEWZHODLMWIoQQnWEA8M84s80KwhbtwpvDTPCiBDC6BZ9ieUIIdQdYexb95tYjhDCdhEOEEvctGmVIOwrv8V9mhaEugifpHlB2NwJIUx3Qgj1/Y7H7ZoYhM2dEEL9A+GXZgbhRzxu08wgbO7XDIR6u69CCE/3VQhhus9RCFXd5yiE6X6PQqjq/gghTPdHCKGq+yOEUPbnKISn+58QQh3uYxTCdL9lIFT1e4QQPjf81EpBmO5jFEJV9zEKoaq7IISq7oIQpvsihFDpLgih0l0QQqW7IIRKd0EIlUcM2tcWhFCq7r8JCJXuQxRC6eU+RCFUVnNACKV8uQFC2Jfluk7L9tMeHdMAAIAwAMMy1+xzomFJa6HpovBta55CFKIQhQpRiEIUKkQhClGoEIUoRKFCFKIQhQpRiEIUKkQhClGoEIUoRKFCFKIQhQpRiEImKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFKJQIQpRiEKFKEQhChWiEIUoVIhCFJIDe7RRGnHfw4wAAAAASUVORK5CYII='
let base64Image = base64String.split(';base64,').pop();

fs.writeFile('./image.png', base64Image, {encoding: 'base64'}, function(err) {
  console.log('File created');
});

let image64File = fs.readFileSync('./image.png')

newImage(jsonData, image64File)

I hope this can help you and other people that might need it in the future.