2012-11-09 5 views
1

나는 이미지를 처리하고 확대 된 버전에 쌍 선형 보간을 추가하는 다음 웹 워커를 작성했습니다.순수 자바 스크립트 이미지 축소하기

이미지를 크게 만드는 데는 효과적이지만 이미지를 더 작게 만들 필요가 있습니다.

내 이해는 보간은 크기를 줄이지 않고 확대하는 것입니다.

this.addEventListener('message', function(event) { 

    var src = event.data.imageData, 
     dest = event.data.imageDataNew 

     postMessage({ 
      'imageData':bilinear(src, dest, scale) 
     }); 

}, false); 

    function ivect(ix, iy, w) { 
     // byte array, r,g,b,a 
     return((ix + w * iy) * 4); 
    } 

function bilinear(srcImg, destImg, scale) { 
     // c.f.: wikipedia english article on bilinear interpolation 
     // taking the unit square, the inner loop looks like this 
     // note: there's a function call inside the double loop to this one 
     // maybe a performance killer, optimize this whole code as you need 
     function inner(f00, f10, f01, f11, x, y) { 
      var un_x = 1.0 - x; var un_y = 1.0 - y; 
      return (f00 * un_x * un_y + f10 * x * un_y + f01 * un_x * y + f11 * x * y); 
     } 
     var i, j; 
     var iyv, iy0, iy1, ixv, ix0, ix1; 
     var idxD, idxS00, idxS10, idxS01, idxS11; 
     var dx, dy; 
     var r, g, b, a; 
     for (i = 0; i < destImg.height; ++i) { 
      iyv = i/scale; 
      iy0 = Math.floor(iyv); 
      // Math.ceil can go over bounds 
      iy1 = (Math.ceil(iyv) > (srcImg.height-1) ? (srcImg.height-1) : Math.ceil(iyv)); 
      for (j = 0; j < destImg.width; ++j) { 
       ixv = j/scale; 
       ix0 = Math.floor(ixv); 
       // Math.ceil can go over bounds 
       ix1 = (Math.ceil(ixv) > (srcImg.width-1) ? (srcImg.width-1) : Math.ceil(ixv)); 
       idxD = ivect(j, i, destImg.width); 
       // matrix to vector indices 
       idxS00 = ivect(ix0, iy0, srcImg.width); 
       idxS10 = ivect(ix1, iy0, srcImg.width); 
       idxS01 = ivect(ix0, iy1, srcImg.width); 
       idxS11 = ivect(ix1, iy1, srcImg.width); 
       // overall coordinates to unit square 
       dx = ixv - ix0; dy = iyv - iy0; 
       // I let the r, g, b, a on purpose for debugging 
       r = inner(srcImg.data[idxS00], srcImg.data[idxS10], 
        srcImg.data[idxS01], srcImg.data[idxS11], dx, dy); 
       destImg.data[idxD] = r; 

       g = inner(srcImg.data[idxS00+1], srcImg.data[idxS10+1], 
        srcImg.data[idxS01+1], srcImg.data[idxS11+1], dx, dy); 
       destImg.data[idxD+1] = g; 

       b = inner(srcImg.data[idxS00+2], srcImg.data[idxS10+2], 
        srcImg.data[idxS01+2], srcImg.data[idxS11+2], dx, dy); 
       destImg.data[idxD+2] = b; 

       a = inner(srcImg.data[idxS00+3], srcImg.data[idxS10+3], 
        srcImg.data[idxS01+3], srcImg.data[idxS11+3], dx, dy); 
       destImg.data[idxD+3] = a; 
      } 
     } 

     return destImg; 
    } 

저는 Lancosz 웹 워커를 작성하여 훌륭한 결과를 얻었지만 속도는 느립니다. 내가 찾고있는 것은 그 사이에 뭔가있는 것이다.

누구나 Bilinear/Bicubic 축소 필터의 합리적으로 빠른 자바 스크립트 구현을 알고 있습니까?

내가 처리 할 이미지의 종류는 5000x5000만큼 커질 수 있으며 1000x1000으로 축소됩니다.

성능이 약 10 초 미만이면 정상입니다.

+0

http://www.grantgalitz.org/image_resize/

(JS에서 게임 보이 컬러 에뮬레이터의 저자) 그랜트 Galitz에 의해 크기를 조정하고 기본 캔버스의 drawImage의 ISN와 아래 이미지를 확장 순수 자바 스크립트 이미지에서 매우 좋은 결과를 보았다 수용 할만한가? – Shmiddty

+0

아쉽게도 아니요, 축소 된 이미지는 5000x5000px에서 1000x1000px로 갈 때 상당히보기 흉하게 보입니다. – gordyr

답변

2

나는