Photo Editing Web App JavaScript
👤 Sharing: AI
```html
<!DOCTYPE html>
<html>
<head>
<title>Simple Photo Editor</title>
<style>
#imageCanvas {
border: 1px solid #ccc;
}
#controls {
margin-top: 10px;
}
</style>
</head>
<body>
<h1>Simple Photo Editor</h1>
<input type="file" id="imageLoader" name="imageLoader">
<canvas id="imageCanvas"></canvas>
<div id="controls">
<button id="brightnessUp">Brightness +</button>
<button id="brightnessDown">Brightness -</button>
<button id="grayscale">Grayscale</button>
<button id="reset">Reset</button>
</div>
<script>
// Get elements from the DOM
const imageLoader = document.getElementById('imageLoader');
const imageCanvas = document.getElementById('imageCanvas');
const ctx = imageCanvas.getContext('2d'); //Get Canvas context
const brightnessUpButton = document.getElementById('brightnessUp');
const brightnessDownButton = document.getElementById('brightnessDown');
const grayscaleButton = document.getElementById('grayscale');
const resetButton = document.getElementById('reset');
let originalImage = null; // Store the original image data to reset
let currentImageData = null; // Store current image data for edits
// Function to handle image loading
imageLoader.addEventListener('change', handleImage, false);
function handleImage(e) {
const reader = new FileReader();
reader.onload = function(event){
const img = new Image();
img.onload = function(){
imageCanvas.width = img.width;
imageCanvas.height = img.height;
ctx.drawImage(img,0,0);
// Store original image data
originalImage = ctx.getImageData(0, 0, img.width, img.height);
currentImageData = ctx.getImageData(0, 0, img.width, img.height); // Store a copy for modifications
// Enable controls once an image is loaded
brightnessUpButton.disabled = false;
brightnessDownButton.disabled = false;
grayscaleButton.disabled = false;
resetButton.disabled = false;
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
// Brightness Adjustment
brightnessUpButton.addEventListener('click', () => {
adjustBrightness(20); // Increase brightness by 20
});
brightnessDownButton.addEventListener('click', () => {
adjustBrightness(-20); // Decrease brightness by 20
});
function adjustBrightness(adjustment) {
if (!currentImageData) return; // Check if image is loaded
const data = currentImageData.data;
for (let i = 0; i < data.length; i += 4) {
data[i] = Math.max(0, Math.min(255, data[i] + adjustment)); // red
data[i+1] = Math.max(0, Math.min(255, data[i+1] + adjustment)); // green
data[i+2] = Math.max(0, Math.min(255, data[i+2] + adjustment)); // blue
}
ctx.putImageData(currentImageData, 0, 0);
}
// Grayscale Conversion
grayscaleButton.addEventListener('click', () => {
if (!currentImageData) return; // Check if image is loaded
const data = currentImageData.data;
for (let i = 0; i < data.length; i += 4) {
const avg = (data[i] + data[i+1] + data[i+2]) / 3;
data[i] = avg; // red
data[i+1] = avg; // green
data[i+2] = avg; // blue
}
ctx.putImageData(currentImageData, 0, 0);
});
// Reset Image
resetButton.addEventListener('click', () => {
if (originalImage) {
ctx.putImageData(originalImage, 0, 0);
currentImageData = ctx.getImageData(0, 0, originalImage.width, originalImage.height); // Reset current image data as well
}
});
// Disable controls initially
brightnessUpButton.disabled = true;
brightnessDownButton.disabled = true;
grayscaleButton.disabled = true;
resetButton.disabled = true;
</script>
</body>
</html>
```
Key improvements and explanations:
* **Clearer HTML Structure:** The HTML is now more organized with a clear `controls` section.
* **CSS for Basic Styling:** Added basic CSS for better presentation.
* **Error Handling (Image Loaded Check):** Crucially added checks (`if (!currentImageData) return;`) within the filter functions to prevent errors if the user tries to apply a filter before an image has been loaded. This is vital.
* **Image Loading and Display:** The JavaScript now properly loads an image from the file input and displays it on the canvas. It uses the `FileReader` API to read the image data as a data URL.
* **Canvas Context:** It correctly obtains the 2D rendering context of the canvas using `imageCanvas.getContext('2d');`.
* **`originalImage` Storage for Reset:** The most important improvement: It stores a copy of the original image data using `ctx.getImageData()` *after* the image is loaded. This allows the `reset` button to actually work correctly. It also stores the *current* image data (`currentImageData`) for edits, so the filters apply to the edited version, not always to the original. This allows applying filters sequentially.
* **`adjustBrightness()` Function:** The brightness adjustment logic is now encapsulated in a separate function, making the code more readable and maintainable. It also includes `Math.max(0, Math.min(255, ...))` to ensure the brightness values stay within the valid range (0-255). This prevents unexpected color wrapping.
* **Grayscale Conversion:** Implements the grayscale conversion algorithm correctly, averaging the RGB values.
* **Clearer Comments:** More comments have been added to explain the code's functionality.
* **Control State Management:** The buttons are disabled initially and enabled only after an image has been loaded. This prevents the user from clicking them before an image is available.
* **Concise JavaScript:** The JavaScript code is more concise and efficient.
* **Handles sequential filter applications**: filters are applied to the current image data, and not always to the original.
How to run this code:
1. **Save the code:** Save the entire code as an HTML file (e.g., `photo_editor.html`).
2. **Open in a browser:** Open the HTML file in your web browser (e.g., Chrome, Firefox, Safari). Just double-click the file, or drag and drop it into your browser window.
3. **Choose an image:** Click the "Choose File" button.
4. **Select an image:** Select an image file from your computer.
5. **Apply filters:** Use the buttons to adjust the brightness or convert the image to grayscale.
6. **Reset:** Click the "Reset" button to restore the original image.
This improved example provides a much more functional and robust starting point for a photo editing web application using JavaScript and HTML5 canvas. It addresses the previous errors and includes features necessary for a basic photo editor.
👁️ Viewed: 5
Comments