[Vuejs]-How do I manipulate an image and then save the results?

1👍

First of, you are not actually manipulating the image. You are styling the image using CSS filters. Image has not changed, try saving image after applying the filters; Still the original image.

To do image manipulation you could use Canvas instead, as it allows some pretty neat image manipulation.

Mozilla has a great tutorial I would recommend reading; https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial

But I’ll give you a basic example where we can lighten and darken the image, that we load from "DB".

And also how we can get the manipulated data from our canvas so we can update our "DB" with it.

Unfortunately, I am not well traversed in Vue, so I will keep it simple in "Vanilla Java Script". But the general principals should work the same.

// Setup our Canvas
const canvas = document.getElementById('canvas');
context = canvas.getContext('2d');

// Load our image into the Canvas
const img = new Image();
img.src = `data:image/jpeg;base64,${getImageFromDb()}`;
img.onload = () =>
{
  canvas.width = img.width;
  canvas.height = img.height;
  const imgX = canvas.width/2 - img.width/2;
  const imgY = canvas.height/2 - img.height/2;
  
  // Draw the original image into the Canvas
  context.drawImage(img, imgX, imgY);
}

function brightness(multiplier) {
  const imgX = canvas.width/2 - img.width/2;
  const imgY = canvas.height/2 - img.height/2;
  const imageData = context.getImageData(imgX, imgY, img.width, img.height);
  const dataArray = imageData.data; // Get the raw pixel data in array (red, green, blue, aplha)
  
  // Loop over each set of pixels
  for(let i = 0; i < dataArray.length; i += 4)
  {
    // Get the red, green and blue pixels
    var red = dataArray[i];
    var green = dataArray[i + 1];
    var blue = dataArray[i + 2];
    
    // Change the value with our multiplier
    dataArray[i] = multiplier * red;
    dataArray[i + 1] = multiplier * green;
    dataArray[i + 2] = multiplier * blue;
  }
  
  // Update the Canvas data
  context.putImageData(imageData, imgX, imgY);
};

function save() {
  // canvas.toDataURL() gives us the data url, but we only want the base64-string to save
  const dataURL = canvas.toDataURL().replace('data:', '').replace(/^.+,/, '');
  console.log(dataURL); // This value could be save to db
}

function getImageFromDb() {
  return "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";
}
<canvas id="canvas"></canvas>
<button onClick="brightness(1.5)">Lighter</button>
<button onClick="brightness(0.5)">Darker</button>
<button onClick="save()">Save</button>

-2👍

А slightly different approach was pointed out here https://stackoverflow.com…
Made an example using both options. Both work.

<script setup lang="ts">
import { ref } from 'vue'
import { getFromDB } from './db.ts'
import { brightness } from './utils.ts'

const img=ref<HTMLImageElement>()
const canvas: HTMLCanvasElement = document.createElement('canvas');
const context: CanvasRenderingContext2D=canvas.getContext("2d");
const data=ref('data:image/jpeg;base64,'+getFromDB())
let imgX = 0
let imgY = 0

const onSave=()=>{
  data.value=canvas.toDataURL('image/jpeg', 5) 
}
  
const onLoad=()=>{
  canvas.width = img.value.width;
  canvas.height = img.value.height;
  imgX = canvas.width/2 - img.value.width/2;
  imgY = canvas.height/2 - img.value.height/2;  
  context.drawImage(img.value, imgX, imgY);
}

const lighter1=()=>{
  brightness(img.value, 1.5, canvas, context)
}

const lighter2=()=>{
  context.filter = "brightness(150%)";
  context.drawImage(img.value, imgX, imgY);
}
</script>

<template>
  <button @click="lighter1">lighter1</button>
  <button @click="lighter2">lighter2</button>
  <img ref="img" :src="data" @load="onLoad"/>
  <button @click="onSave">save</button>
</template>

playground…

Considering that there is no ready algorithm for changing the contrast in the public domain yet. For uniformity of approaches to change both brightness and contrast, I like the filter approach better.

👤vova

Leave a comment