Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
4.8 kB
1
Indexable
Never
import React, { useState, useEffect, useRef } from 'react'
import './styles.css'

function ImageWithSliders() {
  const [brightness, setBrightness] = useState(100)
  const [zoom, setZoom] = useState(100)
  const [contrast, setContrast] = useState(100)
  const [gamma, setGamma] = useState(1)
  const [imageUrl, setImageUrl] = useState(
    'https://upload.wikimedia.org/wikipedia/commons/e/e5/Gamma_correction_test_picture.png'
  )

  const canvasRef = useRef(null)

  useEffect(() => {
    if (canvasRef.current) {
      // Load the image from a URL
      const img = new Image()
      img.crossOrigin = 'anonymous'
      img.src = imageUrl

      // Wait for the image to load
      img.onload = function () {
        // Get the canvas and context objects
        const canvas = canvasRef.current
        const ctx = canvas.getContext('2d')

        // Set the canvas height and width to match the size of the image
        canvas.width = img.width
        canvas.height = img.height

        // Draw the image onto the canvas
        ctx.drawImage(img, 0, 0)

        // Get the image data from the canvas
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
        const data = imageData.data

        // Perform adjustments on each pixel
        for (let i = 0; i < data.length; i += 4) {
          // Brightness
          let r = data[i] + brightness * 2 - 255
          let g = data[i + 1] + brightness * 2 - 255
          let b = data[i + 2] + brightness * 2 - 255

          // Contrast
          r = (contrast / 100) * (r - 128) + 128
          g = (contrast / 100) * (g - 128) + 128
          b = (contrast / 100) * (b - 128) + 128

          // Gamma Correction
          r = Math.pow(r / 255, gamma) * 255
          g = Math.pow(g / 255, gamma) * 255
          b = Math.pow(b / 255, gamma) * 255

          // Set the adjusted pixel values
          data[i] = r
          data[i + 1] = g
          data[i + 2] = b
        }

        // Put the modified image data back onto the canvas
        ctx.putImageData(imageData, 0, 0)
      }
    }
  }, [imageUrl, brightness, contrast, gamma])

  const handleSliderChange = (event) => {
    switch (event.target.name) {
      case 'brightness':
        setBrightness(event.target.value)
        break
      case 'zoom':
        setZoom(event.target.value)
        break
      case 'contrast':
        setContrast(event.target.value)
        break
      case 'gamma':
        setGamma(event.target.value)
        break
      default:
        break
    }
  }

  const saveImage = () => {
    const canvas = canvasRef.current
    const link = document.createElement('a')
    link.download = 'modified-image.png'
    link.href = canvas.toDataURL()
    link.click()
  }

  const style = {
    transform: `scale(${zoom / 100})`,
    objectFit: 'cover',
    objectPosition: 'center',
    width: '100%',
    height: '400px',
    mixBlendMode: 'difference',
  }

  return (
    <div className="container">
      <div className="image-container">
        <canvas
          ref={canvasRef}
          style={{
            ...style,
            filter: `brightness(${brightness}%) contrast(${contrast}%)`,
          }}
        />
      </div>
      <div className="slider-container">
        <div className="slider-wrapper">
          <label htmlFor="brightness">Brightness:</label>
          <input
            type="range"
            name="brightness"
            min="0"
            max="200"
            value={brightness}
            onChange={handleSliderChange}
          />
        </div>
        <div className="slider-wrapper">
          <label htmlFor="zoom">Zoom:</label>
          <input
            type="range"
            name="zoom"
            min="0"
            max="200"
            value={zoom}
            onChange={handleSliderChange}
          />
        </div>
        <div className="slider-wrapper">
          <label htmlFor="contrast">Contrast:</label>
          <input
            type="range"
            name="contrast"
            min="0"
            max="200"
            value={contrast}
            onChange={handleSliderChange}
          />
        </div>
        <div className="slider-wrapper">
          <label htmlFor="gamma">Gamma Correction:</label>
          <input
            type="range"
            name="gamma"
            min="-100"
            max="100"
            step="0.1"
            value={gamma}
            onChange={handleSliderChange}
          />
        </div>
        <button onClick={saveImage}>Save Image</button>
      </div>
    </div>
  )
}

export default ImageWithSliders