Photo by Jackson Sophat on Unsplash
HTML and JavaScript Made Easy: Create an Image Conversion Tool with ChatGPT
Learn How to Build a Simple Image Conversion Tool with Drag-and-Drop Interface using ChatGPT
In this Blog I will share how I created a simple website using HTML and JS using ChatGPT. I will guide you how you can similarly give prompts and create your website with similar or slight modifications.
Live Website Link
This is a great project if you are applying for internships for a Web development role.
The website will have the following functionalities:
Allows the user to select an image file by clicking on the "Click or drag and drop an image here" area or by clicking the hidden file input element.
Displays the selected image below the dropzone, with the ability to set the JPEG quality via a range input element.
Converts the selected image to a 500px wide JPEG format and displays it below the dropzone.
Generates a data URI for the converted image and displays it in a text area element, allowing the user to copy and paste the image code elsewhere.
Calculates and displays the size of the converted JPEG in bytes.
Prompt 1(Basic website):
User:
HTML and JavaScript for a page where a user can drag and drop an image onto a div and that image will then be turned into a 500px wide JPEG displayed below on the page, plus a text area containing a
<img src= data URI>
image that can be copied and pasted out.
Assistant:
To create an HTML page where a user can drag and drop an image onto a div
, and then have that image converted to a 500px wide JPEG displayed below on the page, along with a textarea containing an <img src= data URI>
image that can be copied and pasted out, you can use the following HTML and JavaScript code:
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Image</title>
<style>
#dropzone {
width: 500px;
height: 300px;
border: 2px dashed #ccc;
text-align: center;
padding: 20px;
margin-bottom: 20px;
}
#output {
width: 500px;
margin-bottom: 20px;
}
textarea {
width: 500px;
height: 100px;
}
</style>
</head>
<body>
<div id="dropzone">Drag and drop an image here</div>
<img id="output" src="" alt="Converted Image" />
<textarea id="imgDataUri" readonly><textarea>
<script>
const dropzone = document.getElementById('dropzone');
const output = document.getElementById('output');
const imgDataUri = document.getElementById('imgDataUri');
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '#f0f0f0';
});
dropzone.addEventListener('dragleave', () => {
dropzone.style.backgroundColor = '';
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '';
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const aspectRatio = img.height / img.width;
canvas.width = 500;
canvas.height = 500 * aspectRatio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const dataUrl = canvas.toDataURL('image/jpeg');
output.src = dataUrl;
imgDataUri.value = `<img src="${dataUrl}" alt="Converted Image" />`;
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
} else {
alert('Please drop an image file.');
}
});
</script>
</body>
</html>
In this code, we define a div
element with the ID dropzone
that serves as the drop zone for the image. We also define an img
element with the ID output
to display the converted image and a textarea
element with the ID imgDataUri
to display the <img src= data URI>
code.
The JavaScript code listens for the dragover
, dragleave
, and drop
events on the dropzone
element. When an image is dropped onto the dropzone
, the code reads the image file, resizes it to 500px wide while maintaining the aspect ratio, converts it to a JPEG format, and displays it in the output
image element. The data URI of the image is also displayed in the imgDataUri
text area, ready to be copied and pasted out.
Prompt 2(Add Slider):
User:
Add a slider to control the JPEG quality from 0 to 100 - as the slider is moved the JPEG and the text area should both update
assistant: To add a slider that controls the JPEG quality and updates the JPEG and the textarea as the slider is moved, you can modify the existing code as follows:
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Image</title>
<style>
#dropzone {
width: 500px;
height: 300px;
border: 2px dashed #ccc;
text-align: center;
padding: 20px;
margin-bottom: 20px;
}
#output {
width: 500px;
margin-bottom: 20px;
}
textarea {
width: 500px;
height: 100px;
}
</style>
</head>
<body>
<div id="dropzone">Drag and drop an image here</div>
<label for="qualityRange">JPEG Quality: <span id="qualityValue">75</span></label>
<input type="range" id="qualityRange" min="0" max="100" value="75" />
<img id="output" src="" alt="Converted Image" />
<textarea id="imgDataUri" readonly><textarea>
<script>
const dropzone = document.getElementById('dropzone');
const output = document.getElementById('output');
const imgDataUri = document.getElementById('imgDataUri');
const qualityRange = document.getElementById('qualityRange');
const qualityValue = document.getElementById('qualityValue');
let imgSrc;
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '#f0f0f0';
});
dropzone.addEventListener('dragleave', () => {
dropzone.style.backgroundColor = '';
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '';
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
imgSrc = e.target.result;
updateImage();
};
reader.readAsDataURL(file);
} else {
alert('Please drop an image file.');
}
});
qualityRange.addEventListener('input', () => {
qualityValue.textContent = qualityRange.value;
updateImage();
});
function updateImage() {
if (!imgSrc) return;
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const aspectRatio = img.height / img.width;
canvas.width = 500;
canvas.height = 500 * aspectRatio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const quality = qualityRange.value / 100;
const dataUrl = canvas.toDataURL('image/jpeg', quality);
output.src = dataUrl;
imgDataUri.value = `<img src="${dataUrl}" alt="Converted Image" />`;
};
img.src = imgSrc;
}
</script>
</body>
</html>
In this modified code, we added a label
and an input
element of type range
with the ID qualityRange
to create the slider for controlling the JPEG quality. The qualityValue
span element displays the current value of the slider.
We also added an event listener for the input
event on the qualityRange
slider. When the slider value changes, the updateImage
function is called to update the displayed image and the textarea content.
The updateImage
function reads the current value of the slider, converts it to a quality factor between 0 and 1, and uses it to generate a new JPEG image with the specified quality. The toDataURL
method accepts the second argument as the quality factor, which determines the quality of the generated JPEG image. The updated image is then displayed in the output
image element, and the data URI of the image is displayed in the imgDataUri
textarea.
The imgSrc
variable is used to store the source of the original image, so we can regenerate the JPEG image with different quality settings as the slider is moved. The updateImage
function is also called when a new image is dropped onto the dropzone
, ensuring that the image is displayed with the current quality setting from the slider.
Prompt 3(Size of JPEG in Bytes):
User:
Update the design so each element is on a newline, and add a div that shows the size of the JPEG in bytes
assistant: To update the design so that each element is on a new line, and to add a div that shows the size of the JPEG in bytes, you can modify the existing code as follows:
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Image</title>
<style>
#dropzone {
width: 500px;
height: 300px;
border: 2px dashed #ccc;
text-align: center;
padding: 20px;
margin-bottom: 20px;
}
#output {
width: 500px;
margin-bottom: 20px;
}
textarea {
width: 500px;
height: 100px;
}
.container {
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="dropzone">Drag and drop an image here</div>
<div class="container">
<label for="qualityRange">JPEG Quality: <span id="qualityValue">75</span></label><br>
<input type="range" id="qualityRange" min="0" max="100" value="75" />
</div>
<img id="output" src="" alt="Converted Image" /><br>
<div class="container">
<label for="imgDataUri">Image Data URI:</label><br>
<textarea id="imgDataUri" readonly><textarea>
</div>
<div id="jpegSize">JPEG Size: 0 bytes</div>
<script>
const dropzone = document.getElementById('dropzone');
const output = document.getElementById('output');
const imgDataUri = document.getElementById('imgDataUri');
const qualityRange = document.getElementById('qualityRange');
const qualityValue = document.getElementById('qualityValue');
const jpegSize = document.getElementById('jpegSize');
let imgSrc;
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '#f0f0f0';
});
dropzone.addEventListener('dragleave', () => {
dropzone.style.backgroundColor = '';
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '';
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
imgSrc = e.target.result;
updateImage();
};
reader.readAsDataURL(file);
} else {
alert('Please drop an image file.');
}
});
qualityRange.addEventListener('input', () => {
qualityValue.textContent = qualityRange.value;
updateImage();
});
function updateImage() {
if (!imgSrc) return;
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const aspectRatio = img.height / img.width;
canvas.width = 500;
canvas.height = 500 * aspectRatio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const quality = qualityRange.value / 100;
const dataUrl = canvas.toDataURL('image/jpeg', quality);
output.src = dataUrl;
imgDataUri.value = `<img src="${dataUrl}" alt="Converted Image" />`;
const size = Math.round(dataUrl.length * 3 / 4); // Approximate size in bytes
jpegSize.textContent = `JPEG Size: ${size}
---
**assistant**: bytes`;
};
img.src = imgSrc;
}
</script>
</body>
</html>
In this modified code, we added <br>
tags after the slider and the image to ensure that each element is on a new line. We also added a new div
element with the ID jpegSize
to display the size of the JPEG in bytes.
We introduced a new variable jpegSize
to reference the div
element that shows the size of the JPEG. In the updateImage
function, we calculate the approximate size of the JPEG in bytes based on the length of the data URL. The size is then displayed in the jpegSize
div.
Note that the calculated size is an approximation because the data URL is base64 encoded, and the actual size of the binary data is roughly 3/4 of the length of the base64 string. The size is rounded to the nearest whole number for display.
The container
class is added to group elements and provide a margin at the bottom for better spacing. The label for the textarea is also added to improve accessibility.
Prompt 4(Add file to Website):
User:
Make it so clicking on the #dropzone div lets the user pick a file with a file picker
assistant: To allow the user to pick a file using a file picker when clicking on the #dropzone div, we can add an element to the HTML and trigger its click event when the #dropzone div is clicked. Here's the updated code:
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Image</title>
<style>
#dropzone {
width: 500px;
height: 300px;
border: 2px dashed #ccc;
text-align: center;
padding: 20px;
margin-bottom: 20px;
cursor: pointer;
}
#output {
width: 500px;
margin-bottom: 20px;
}
textarea {
width: 500px;
height: 100px;
}
.container {
margin-bottom: 20px;
}
#fileInput {
display: none;
}
</style>
</head>
<body>
<div id="dropzone">Click or drag and drop an image here</div>
<input type="file" id="fileInput" accept="image/*">
<!-- Rest of the code remains the same -->
<!-- ... -->
<script>
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
// Rest of the code remains the same
// ...
dropzone.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', () => {
const file = fileInput.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
imgSrc = e.target.result;
updateImage();
};
reader.readAsDataURL(file);
} else {
alert('Please select an image file.');
}
});
// Rest of the code remains the same
// ...
</script>
</body>
</html>
In this updated code, we added an <input type="file">
element with the ID fileInput
to the HTML. The accept="image/*"
attribute ensures that only image files.
Final App:
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop Image</title>
<style>
#dropzone {
width: 500px;
height: 100px;
border: 2px dashed #ccc;
text-align: center;
padding: 20px;
margin-bottom: 20px;
}
#output {
width: 500px;
margin-bottom: 20px;
}
textarea {
width: 500px;
height: 100px;
}
.container {
margin-bottom: 20px;
}
#fileInput {
display: none;
}
</style>
</head>
<body>
<div id="dropzone">Click or drag and drop an image here</div>
<input type="file" id="fileInput" accept="image/*">
<div class="container">
<label for="qualityRange">JPEG Quality: <span id="qualityValue">75</span></label><br>
<input type="range" id="qualityRange" min="0" max="100" value="75" />
</div>
<img id="output" src="" alt="Converted Image" /><br>
<div class="container">
<label for="imgDataUri">Image Data URI:</label><br>
<textarea id="imgDataUri" readonly></textarea>
</div>
<div id="jpegSize">JPEG Size: 0 bytes</div>
<script>
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
dropzone.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', () => {
const file = fileInput.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
imgSrc = e.target.result;
updateImage();
};
reader.readAsDataURL(file);
} else {
alert('Please select an image file.');
}
});
const output = document.getElementById('output');
const imgDataUri = document.getElementById('imgDataUri');
const qualityRange = document.getElementById('qualityRange');
const qualityValue = document.getElementById('qualityValue');
const jpegSize = document.getElementById('jpegSize');
let imgSrc;
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '#f0f0f0';
});
dropzone.addEventListener('dragleave', () => {
dropzone.style.backgroundColor = '';
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.style.backgroundColor = '';
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
imgSrc = e.target.result;
updateImage();
};
reader.readAsDataURL(file);
} else {
alert('Please drop an image file.');
}
});
qualityRange.addEventListener('input', () => {
qualityValue.textContent = qualityRange.value;
updateImage();
});
function updateImage() {
if (!imgSrc) return;
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const aspectRatio = img.height / img.width;
canvas.width = 500;
canvas.height = 500 * aspectRatio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const quality = qualityRange.value / 100;
const dataUrl = canvas.toDataURL('image/jpeg', quality);
output.src = dataUrl;
imgDataUri.value = `<img src="${dataUrl}" alt="Converted Image" />`;
const size = Math.round(dataUrl.length * 3 / 4); // Approximate size in bytes
jpegSize.textContent = `JPEG Size: ${size.toLocaleString()} bytes`;
};
img.src = imgSrc;
}
</script>
</body>
</html>
Thank u for Reading this. ๐