Docker installation instructions
docker run --name heicconverter -v ~/Desktop/heicconverter:/root/heicconverter -p 8080:3000 -it ubuntu /bin/bash
Now you should be inside a docker container, run the following commends
cd ~/heicconverter
apt update; apt install nodejs npm libheif-examples -y
Now setup your express app
npm install express --save
npm init
Copy the rest of this file to your ~/Desktop/heicConverter folder and name it index.js
- To start, back in your docker container run
nodejs index.js
- In your browser, try opening: http://localhost:8080/?url=https://nokiatech.github.io/heif/content/images/autumn_1440x960.heic
// Example usage: http://localhost:8080/?url=https://nokiatech.github.io/heif/content/images/autumn_1440x960.heic
// ?url= should be a url, if its URL encoded, it might break.
// The return response should be the image as a jpg with the corret mimetype.
// Temp folder to save images
const tempFolder = __dirname + '/' // Please include the trailling slash. '/root/heiclambda/'
// Lets you run another program and listen for its output.
const exec = require("child_process").exec
// Used to make external calls, we use this to download the heic file from the url the user gives us.
const request = require('request')
// Access the filesystem to save temporary files.
const fs = require('fs')
// Webserver
const express = require('express')
// Application
const app = express()
const port = 3000
app.get('/', (req, res) => {
// Query string example.com?url=XXXXXX
let url = req.query.url
// If the url parameter is missing, lets return a 404 and tell the user how to use this service.
if(url == undefined || url == '') {
res.status(404).send('Include the file in the url. <br/>Example: url/?url=http://example.com/file.heic')
}
// We are going to save the file to the local filesystem. Lets use the current time, it will help prevent collisions if multiple images are being called on the same instance at once.
var currentTime = (new Date()).getTime()
let heicLocation = tempFolder + currentTime + '.heic'
let jpgLocation = tempFolder + currentTime + '.jpg'
// Download the file from the url in the query parameter
request
.get(url)
.on('end', ()=> {
save(heicLocation, jpgLocation, (error) => {
// If we run into an error converting the file, lets delete the temp file and let the user know.
if (error) {
fs.unlinkSync(heicLocation)
res.status(500).send('Invalid .heic file')
} else {
// File converted successfully, lets send the file to the user and delete the temp files.
// Remove the heic file
fs.unlinkSync(heicLocation)
// Send the file to the user and delete the temp file once the user has received the file.
res.sendFile(jpgLocation, (error) => {
// Remove the jpg after we sent it to the user
fs.unlinkSync(jpgLocation)
})
}
})
})
// While we are downloading the file, stream it a file on the local filesystem.
.pipe(fs.createWriteStream(heicLocation))
})
// Start the server and listen on a port.
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
// Helper save function. This runs the `heif-convert` application to actually convert the file.
// - heicLocation: is the file on disk that contains the file we want to convert.
// - jpgLocation: is the destination file on the disk that we want to write to. This file will be replaced if it exists. (I believe)
// - callback: this is a function that will be called once the save operation is complete.
// - callback bool parameter: return `true` if there is an error.
var save = (heicLocation, jpgLocation, callback) => {
exec('/usr/bin/heif-convert ' + heicLocation + ' ' + jpgLocation, (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`)
callback(true)
return
}
if (stderr) {
console.log(`stderr: ${stderr}`)
callback(true)
return
}
console.log(`stdout: ${stdout}`)
callback(false)
});
}