@VidKein
FRONT END WEB DEVELOPER (junior)

Хочу реализовать улучшение резкости фотографии при изменении положении range(input)?

Предполагается что изображение будет располагаться на холсте, чтобы в реальном времени редактировать картинку. Реализована свертка с матрицей [0, -1, 0, -1, 5, -1.0, -1, 0], изменения происходит статично (сразу при загрузки фото на "canvas"). Но не могу реализовать изменение интенсивности повышения резкости с помощью увеличения микса.
Подскажите пожалуйста как это реализовать, с помощью обработки буферизованных типизированных массивов. Планируется редактировать фото с большим размером, в среднем 2500 рх.

<canvas id="canvas"></canvas>
<input type="range" name="Sharp" id="mix" min="0.1" max="100" step="0.01" value="0">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAGiSURBVDhPlZE7rkFRFIYdDiJECCERRGjMQCjUGgOQGIIYggQToDEIrU6iUFDp1FSEICEeEe/7nbs2xa3clZx99lr7///10l6vl+k/pgicmqZJCLvf7xLRdV2F3hjt+XzicPlwer3eeDx2OBzn8zmdTqdSqQ/aQHLjd71e+/3+ZrOBPxgMFouFIGKxGAReo9FoNps1m81GBh6m02m1Wl2v116v12q1BoNBn8+Hu1wuYSIUCoVqtVo4HNYlERput9vpdJ5Op2QyWSqVXC7XbrdrNBqTySSRSEDjCaSZD7NYLHa7fb/fx+PxcrmMcKvVwoUZiUQOh4PNZiOzIki5l8uFLvP5/OPxIHu73a7X6+TJ5XLH41FaVQTQ+GKgESMbA0WSkxEL5hf/LgkfHHqdTodUlUqlUChwbrfbbrdLe0JAUZWEzO1242E2mzWbTbSLxSKToGlGxDC4Y9CMRYo8hcpY2cNoNPL7/avVCi2Px8NaAoEA+Q0wIX5kGA6H8/mcBTMx5sMAEAbEotBig5lMBmnV7qdEiYgr9ieoMnxvakrfmsn0AyLUEuUB9n4LAAAAAElFTkSuQmCC" alt="" style="display: none;">

<script>
  //Setting the sharpness value
  let mix = document.getElementById("mix");
  mix.addEventListener("input", ()=>{update(mix)});  
  //create canvas
  canvas = document.getElementById("canvas");
  context = canvas.getContext("2d");
  //uploading a picture
  let img = new Image();  
  img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAGiSURBVDhPlZE7rkFRFIYdDiJECCERRGjMQCjUGgOQGIIYggQToDEIrU6iUFDp1FSEICEeEe/7nbs2xa3clZx99lr7///10l6vl+k/pgicmqZJCLvf7xLRdV2F3hjt+XzicPlwer3eeDx2OBzn8zmdTqdSqQ/aQHLjd71e+/3+ZrOBPxgMFouFIGKxGAReo9FoNps1m81GBh6m02m1Wl2v116v12q1BoNBn8+Hu1wuYSIUCoVqtVo4HNYlERput9vpdJ5Op2QyWSqVXC7XbrdrNBqTySSRSEDjCaSZD7NYLHa7fb/fx+PxcrmMcKvVwoUZiUQOh4PNZiOzIki5l8uFLvP5/OPxIHu73a7X6+TJ5XLH41FaVQTQ+GKgESMbA0WSkxEL5hf/LgkfHHqdTodUlUqlUChwbrfbbrdLe0JAUZWEzO1242E2mzWbTbSLxSKToGlGxDC4Y9CMRYo8hcpY2cNoNPL7/avVCi2Px8NaAoEA+Q0wIX5kGA6H8/mcBTMx5sMAEAbEotBig5lMBmnV7qdEiYgr9ieoMnxvakrfmsn0AyLUEuUB9n4LAAAAAElFTkSuQmCC";     
  //set the size of reserved memory
  canvas.width = img.width;
  canvas.height = img.height;
  //getting started with canvas
  img.onload = update;

  function sharpen (context, width, height, mix) {   
    //create an empty element with the given width/height
    let dstData = context.createImageData(width,height),
        dstBuff = new Uint32Array(dstData.data.buffer);        
    //collection of information
    let pixel = context.getImageData(0,0,width,height),
        data = new Uint32Array(pixel.data.buffer);    
    //Everything to work with the matrix
    let kernel = [[0, -1, 0],// matrixа
                 [-1, 5, -1],
                 [0, -1, 0]],
        katet = Math.round(Math.sqrt(kernel.length))+1,//root 9=3
        half = (katet * 0.5) | 0,//3*0.5=1.5 discard values ​​after the decimal point
        offset = 0,//offset - coefficient
        div = 1.0;//div - divider        
    //pixel processing
    let dstIndex = 0;
      for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
          let r = 0, g = 0, b = 0;
          for (let sy = 0; sy < katet; sy++) {
            const yy = Math.min(height - 1, Math.max(0, y + sy - half));
            for (let sx = 0; sx < katet; sx++) {
              const xx = Math.min(width - 1, Math.max(0, x + sx - half));
              let pix = data[yy * width + xx];                    
              r += ((pix & 0xFF) * kernel[sy][sx]);
              g += ((((pix) >> 8) & 0xFF) * kernel[sy][sx]);
              b += ((((pix) >> 16) & 0xFF) * kernel[sy][sx]); 
            }
          }        
          const a = data[y * width + x] & 0xFF000000;
          r = (Math.min(255, Math.max(0, offset + (r / div)))) & 0xFF;
          g = (Math.min(255, Math.max(0, offset + (g / div)))) & 0xFF;
          b = (Math.min(255, Math.max(0, offset + (b / div)))) & 0xFF;             
          dstBuff[dstIndex++] = a | ((b) << 16) | ((g) << 8) | r;//fill with changes
        }
      }
      context.putImageData(dstData, 0, 0);//overwriting the canvas with new data         
      }
 
function update() {
  context.drawImage(img, 0, 0);  
  sharpen(context, img.width, img.height, parseInt(mix.value) * 0.01)
}
</script>
  • Вопрос задан
  • 68 просмотров
Пригласить эксперта
Ответы на вопрос 1
@VidKein Автор вопроса
FRONT END WEB DEVELOPER (junior)
Вопрос решен.
Ниже предоставлен рабочий код.
<canvas id="canvas"></canvas>
<input type="range" name="Sharp" id="mix" min="0.1" max="100" step="0.01" value="0">

//Setting the sharpness value
let mix = document.getElementById("mix");
  mix.addEventListener("input", ()=>{update(mix)});  
  //create canvas
  canvas = document.getElementById("canvas");
  context = canvas.getContext("2d");
  //uploading a picture
  let img = new Image();  
  img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAGiSURBVDhPlZE7rkFRFIYdDiJECCERRGjMQCjUGgOQGIIYggQToDEIrU6iUFDp1FSEICEeEe/7nbs2xa3clZx99lr7///10l6vl+k/pgicmqZJCLvf7xLRdV2F3hjt+XzicPlwer3eeDx2OBzn8zmdTqdSqQ/aQHLjd71e+/3+ZrOBPxgMFouFIGKxGAReo9FoNps1m81GBh6m02m1Wl2v116v12q1BoNBn8+Hu1wuYSIUCoVqtVo4HNYlERput9vpdJ5Op2QyWSqVXC7XbrdrNBqTySSRSEDjCaSZD7NYLHa7fb/fx+PxcrmMcKvVwoUZiUQOh4PNZiOzIki5l8uFLvP5/OPxIHu73a7X6+TJ5XLH41FaVQTQ+GKgESMbA0WSkxEL5hf/LgkfHHqdTodUlUqlUChwbrfbbrdLe0JAUZWEzO1242E2mzWbTbSLxSKToGlGxDC4Y9CMRYo8hcpY2cNoNPL7/avVCi2Px8NaAoEA+Q0wIX5kGA6H8/mcBTMx5sMAEAbEotBig5lMBmnV7qdEiYgr9ieoMnxvakrfmsn0AyLUEuUB9n4LAAAAAElFTkSuQmCC";     
  //set the size of reserved memory
  canvas.width = img.width;
  canvas.height = img.height;
  //getting started with canvas
  img.onload = update;

  function sharpen (context, width, height, mix) {   
    //create an empty element with the given width/height
    let dstData = context.createImageData(width,height),
        dstBuff = new Uint32Array(dstData.data.buffer);        
    //collection of information
    let pixel = context.getImageData(0,0,width,height),
        data = new Uint32Array(pixel.data.buffer);    
    //Everything to work with the matrix
    let kernel = [[0, -1, 0],// matrixа
                 [-1, 5, -1],
                 [0, -1, 0]],
        katet = Math.round(Math.sqrt(kernel.length))+1,//root 9=3
        half = (katet * 0.5) | 0;//3*0.5=1.5 discard values ​​after the decimal point      
    //pixel processing
    let dstIndex = 0;
      for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
          let r = 0, g = 0, b = 0;
          for (let sy = 0; sy < katet; sy++) {
            const yy = Math.min(height - 1, Math.max(0, y + sy - half));
            for (let sx = 0; sx < katet; sx++) {
              const xx = Math.min(width - 1, Math.max(0, x + sx - half));
              let pix = data[yy * width + xx];                    
              r += ((pix & 0xFF) * kernel[sy][sx]);
              g += ((((pix) >> 8) & 0xFF) * kernel[sy][sx]);
              b += ((((pix) >> 16) & 0xFF) * kernel[sy][sx]); 
            }
          }        
          red = Math.min(255,Math.max(0, (r*mix)+((data[y * width + x] )&0xFF)*(1-mix) ))&0xFF;
          green = Math.min(255, Math.max(0, (g*mix)+(((data[y * width + x])>> 8)&0xFF)*(1-mix) ))&0xFF;
          blue = Math.min(255, Math.max(0, (b*mix)+(((data[y * width + x])>> 16)&0xFF)*(1-mix) ))&0xFF;
          const alfa = data[y * width + x] & 0xFF000000;

          dstBuff[dstIndex++] = red | ((green) << 8) | ((blue) << 16) | alfa | ((blue) << 16);//fill with changes
        }
      }
      context.putImageData(dstData, 0, 0);//overwriting the canvas with new data         
      }
 
function update() {
  canvas.width = img.width;
  canvas.height = img.height;
  context.drawImage(img, 0, 0);  
  sharpen(context, img.width, img.height, parseInt(mix.value) * 0.01)
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы