2014-04-16 39 views
0

我有一个JavaScript算法,我想转换成Java。什么是一些JavaScript表达式的等效GWT/Java语法?

下面是JavaScript代码:

function downScaleCanvas(cv, scale) { 
     if (!(scale < 1) || !(scale > 0)) throw ('scale must be a positive number <1 '); 
     var sqScale = scale * scale; // square scale = area of source pixel within target 
     var sw = cv.width; // source image width 
     var sh = cv.height; // source image height 
     var tw = Math.ceil(sw * scale); // target image width 
     var th = Math.ceil(sh * scale); // target image height 
     var sx = 0, sy = 0, sIndex = 0; // source x,y, index within source array 
     var tx = 0, ty = 0, yIndex = 0, tIndex = 0; // target x,y, x,y index within target array 
     var tX = 0, tY = 0; // rounded tx, ty 
     var w = 0, nw = 0, wx = 0, nwx = 0, wy = 0, nwy = 0; // weight/next weight x/y 
     // weight is weight of current source point within target. 
     // next weight is weight of current source point within next target's point. 
     var crossX = false; // does scaled px cross its current px right border ? 
     var crossY = false; // does scaled px cross its current px bottom border ? 
     var sBuffer = cv.getContext('2d').getImageData(0, 0, sw, sh).data; // source buffer 8 bit rgba 
     var tBuffer = new Float32Array(4 * sw * sh); // target buffer Float32 rgb 
     var sR = 0, sG = 0, sB = 0; // source's current point r,g,b 
     // untested ! 
     var sA = 0; //source alpha  

     for (sy = 0; sy < sh; sy++) { 
      ty = sy * scale; // y src position within target 
      tY = 0 | ty;  // rounded : target pixel's y 
      yIndex = 4 * tY * tw; // line index within target array 
      crossY = (tY != (0 | ty + scale)); 
      if (crossY) { // if pixel is crossing botton target pixel 
       wy = (tY + 1 - ty); // weight of point within target pixel 
       nwy = (ty + scale - tY - 1); // ... within y+1 target pixel 
      } 
      for (sx = 0; sx < sw; sx++, sIndex += 4) { 
       tx = sx * scale; // x src position within target 
       tX = 0 | tx; // rounded : target pixel's x 
       tIndex = yIndex + tX * 4; // target pixel index within target array 
       crossX = (tX != (0 | tx + scale)); 
       if (crossX) { // if pixel is crossing target pixel's right 
        wx = (tX + 1 - tx); // weight of point within target pixel 
        nwx = (tx + scale - tX - 1); // ... within x+1 target pixel 
       } 
       sR = sBuffer[sIndex ]; // retrieving r,g,b for curr src px. 
       sG = sBuffer[sIndex + 1]; 
       sB = sBuffer[sIndex + 2]; 
       sA = sBuffer[sIndex + 3]; 

       if (!crossX && !crossY) { // pixel does not cross 
        // just add components weighted by squared scale. 
        tBuffer[tIndex ] += sR * sqScale; 
        tBuffer[tIndex + 1] += sG * sqScale; 
        tBuffer[tIndex + 2] += sB * sqScale; 
        tBuffer[tIndex + 3] += sA * sqScale; 
       } else if (crossX && !crossY) { // cross on X only 
        w = wx * scale; 
        // add weighted component for current px 
        tBuffer[tIndex ] += sR * w; 
        tBuffer[tIndex + 1] += sG * w; 
        tBuffer[tIndex + 2] += sB * w; 
        tBuffer[tIndex + 3] += sA * w; 
        // add weighted component for next (tX+1) px     
        nw = nwx * scale; 
        tBuffer[tIndex + 4] += sR * nw; // not 3 
        tBuffer[tIndex + 5] += sG * nw; // not 4 
        tBuffer[tIndex + 6] += sB * nw; // not 5 
        tBuffer[tIndex + 7] += sA * nw; // not 6 
       } else if (crossY && !crossX) { // cross on Y only 
        w = wy * scale; 
        // add weighted component for current px 
        tBuffer[tIndex ] += sR * w; 
        tBuffer[tIndex + 1] += sG * w; 
        tBuffer[tIndex + 2] += sB * w; 
        tBuffer[tIndex + 3] += sA * w; 
        // add weighted component for next (tY+1) px     
        nw = nwy * scale; 
        tBuffer[tIndex + 4 * tw ] += sR * nw; // *4, not 3 
        tBuffer[tIndex + 4 * tw + 1] += sG * nw; // *4, not 3 
        tBuffer[tIndex + 4 * tw + 2] += sB * nw; // *4, not 3 
        tBuffer[tIndex + 4 * tw + 3] += sA * nw; // *4, not 3 
       } else { // crosses both x and y : four target points involved 
        // add weighted component for current px 
        w = wx * wy; 
        tBuffer[tIndex ] += sR * w; 
        tBuffer[tIndex + 1] += sG * w; 
        tBuffer[tIndex + 2] += sB * w; 
        tBuffer[tIndex + 3] += sA * w; 
        // for tX + 1; tY px 
        nw = nwx * wy; 
        tBuffer[tIndex + 4] += sR * nw; // same for x 
        tBuffer[tIndex + 5] += sG * nw; 
        tBuffer[tIndex + 6] += sB * nw; 
        tBuffer[tIndex + 7] += sA * nw; 
        // for tX ; tY + 1 px 
        nw = wx * nwy; 
        tBuffer[tIndex + 4 * tw ] += sR * nw; // same for mul 
        tBuffer[tIndex + 4 * tw + 1] += sG * nw; 
        tBuffer[tIndex + 4 * tw + 2] += sB * nw; 
        tBuffer[tIndex + 4 * tw + 3] += sA * nw; 
        // for tX + 1 ; tY +1 px 
        nw = nwx * nwy; 
        tBuffer[tIndex + 4 * tw + 4] += sR * nw; // same for both x and y 
        tBuffer[tIndex + 4 * tw + 5] += sG * nw; 
        tBuffer[tIndex + 4 * tw + 6] += sB * nw; 
        tBuffer[tIndex + 4 * tw + 7] += sA * nw; 
       } 
      } // end for sx 
     } // end for sy 

     // create result canvas 
     var resCV = document.createElement('canvas'); 
     resCV.width = tw; 
     resCV.height = th; 
     var resCtx = resCV.getContext('2d'); 
     var imgRes = resCtx.getImageData(0, 0, tw, th); 
     var tByteBuffer = imgRes.data; 
     // convert float32 array into a UInt8Clamped Array 
     var pxIndex = 0; // 
     for (sIndex = 0, tIndex = 0; pxIndex < tw * th; sIndex += 4, tIndex += 4, pxIndex++) { 
      tByteBuffer[tIndex] = Math.ceil(tBuffer[sIndex]); 
      tByteBuffer[tIndex + 1] = Math.ceil(tBuffer[sIndex + 1]); 
      tByteBuffer[tIndex + 2] = Math.ceil(tBuffer[sIndex + 2]); 
      tByteBuffer[tIndex + 3] = Math.ceil(tBuffer[sIndex + 3]); 
     } 
     // writing result to canvas. 
     resCtx.putImageData(imgRes, 0, 0); 
     return resCV; 
    } 

这里是我做的,到目前为止在Java中:

public static final CanvasElement scaleCanvas(CanvasElement cv, double scale) { 

     if (!(scale < 1) || !(scale > 0)) { 
//   throw new Exception("scale must be a positive number <1 "); 
     } 

     double sqScale = scale * scale; // square scale = area of source pixel within target 
     int sw = cv.getWidth(); // source image width 
     int sh = cv.getHeight(); // source image height 
     double tw = Math.ceil(sw * scale); // target image width 
     double th = Math.ceil(sh * scale); // target image height 
     int sx = 0, sy = 0, sIndex = 0; // source x,y, index within source array 
     double tx = 0, ty = 0; 
     int yIndex = 0, tIndex = 0; // target x,y, x,y index within target array 
     double tX = 0, tY = 0; // rounded tx, ty 
     double w = 0, nw = 0, wx = 0, nwx = 0, wy = 0, nwy = 0; // weight/next weight x/y 
     // weight is weight of current source point within target. 
     // next weight is weight of current source point within next target's point. 
     boolean crossX = false; // does scaled px cross its current px right border ? 
     boolean crossY = false; // does scaled px cross its current px bottom border ? 
     CanvasPixelArray sBuffer = cv.getContext2d().getImageData(0, 0, sw, sh).getData(); // source buffer 8 bit rgba 
     Float32Array tBuffer = TypedArrays.createFloat32Array(4 * sw * sh); 

     double sR = 0, sG = 0, sB = 0; // source's current point r,g,b 
     // untested ! 
     double sA = 0; //source alpha  

     for (sy = 0; sy < sh; sy++) { 
      GWT.log("sy: "+sy+" sh: "+sh); 

      ty = sy * scale; // y src position within target 
      tY = (long)ty;  // rounded : target pixel's y       // ????? 
      yIndex = (int)Math.floor(4 * tY * tw); // line index within target array 
      crossY = (tY != ((long)(ty + scale)));             // ????? 
      if (crossY) { // if pixel is crossing botton target pixel 
       wy = (tY + 1 - ty); // weight of point within target pixel 
       nwy = (ty + scale - tY - 1); // ... within y+1 target pixel 
      } 
      for (sx = 0; sx < sw; sx++, sIndex += 4) { 
       tx = sx * scale; // x src position within target 
       tX = (long)tx; // rounded : target pixel's x        // ????? 
       tIndex = (int)Math.floor(yIndex + tX * 4); // target pixel index within target array     // ????? 
       crossX = (tX != ((int)Math.floor(tx + scale))); 
       if (crossX) { // if pixel is crossing target pixel's right 
        wx = (tX + 1 - tx); // weight of point within target pixel 
        nwx = (tx + scale - tX - 1); // ... within x+1 target pixel 
       } 
       sR = sBuffer.get(sIndex); // retrieving r,g,b for curr src px. 
       sG = sBuffer.get(sIndex + 1); 
       sB = sBuffer.get(sIndex + 2); 
       sA = sBuffer.get(sIndex + 3); 

       if (!crossX && !crossY) { // pixel does not cross 
        // just add components weighted by squared scale. 

        tBuffer.set(tIndex , (float)(tBuffer.get(tIndex)  + sR * sqScale)); 
        tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * sqScale)); 
        tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * sqScale)); 
        tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * sqScale)); 
       } else if (crossX && !crossY) { // cross on X only 
        w = wx * scale; 
        // add weighted component for current px 
        tBuffer.set(tIndex , (float)(tBuffer.get(tIndex)  + sR * w)); 
        tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * w)); 
        tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * w)); 
        tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * w)); 

        // add weighted component for next (tX+1) px     
        nw = nwx * scale; 
        tBuffer.set(tIndex + 4, (float)(tBuffer.get(tIndex + 4) + sR * nw));  // not 3 
        tBuffer.set(tIndex + 5, (float)(tBuffer.get(tIndex + 5) + sG * nw));  // not 4 
        tBuffer.set(tIndex + 6, (float)(tBuffer.get(tIndex + 6) + sB * nw));  // not 5 
        tBuffer.set(tIndex + 7, (float)(tBuffer.get(tIndex + 7) + sA * nw));  // not 6 
       } else if (crossY && !crossX) { // cross on Y only 
        w = wy * scale; 
        // add weighted component for current px 
        tBuffer.set(tIndex , (float)(tBuffer.get(tIndex)  + sR * w)); 
        tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * w)); 
        tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * w)); 
        tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * w)); 

        // add weighted component for next (tY+1) px     
        nw = nwy * scale; 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw) , (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw))  + sR * nw)); // *4, not 3 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 1), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 1)) + sG * nw)); // *4, not 3 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 2), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 2)) + sB * nw)); // *4, not 3 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 3), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 3)) + sA * nw)); // *4, not 3 
       } else { // crosses both x and y : four target points involved 
        // add weighted component for current px 
        w = wx * wy; 
        tBuffer.set(tIndex , (float)(tBuffer.get(tIndex) + sR * w)); 
        tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * w)); 
        tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * w)); 
        tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * w)); 
        // for tX + 1; tY px 
        nw = nwx * wy; 
        tBuffer.set(tIndex + 4, (float)(tBuffer.get(tIndex + 4) + sR * nw)); // same for x 
        tBuffer.set(tIndex + 5, (float)(tBuffer.get(tIndex + 5) + sG * nw)); 
        tBuffer.set(tIndex + 6, (float)(tBuffer.get(tIndex + 6) + sB * nw)); 
        tBuffer.set(tIndex + 7, (float)(tBuffer.get(tIndex + 7) + sA * nw)); 
        // for tX ; tY + 1 px 
        nw = wx * nwy; 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw) , (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw))  + sR * nw)); // same for mul 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 1), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 1)) + sG * nw)); 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 2), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 2)) + sB * nw)); 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 3), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 3)) + sA * nw)); 
        // for tX + 1 ; tY +1 px 
        nw = nwx * nwy; 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 4), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 4)) + sR * nw)); // same for both x and y 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 5), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 5)) + sG * nw)); 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 6), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 6)) + sB * nw)); 
        tBuffer.set((int)Math.floor(tIndex + 4 * tw + 7), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 7)) + sA * nw)); 
       } 
      } // end for sx 
     } // end for sy 


     // create result canvas 
     Canvas resCV = Canvas.createIfSupported(); 
     resCV.getCanvasElement().setWidth((int)Math.floor(tw)); 
     resCV.getCanvasElement().setHeight((int)Math.floor(th)); 
     Context2d resCtx = resCV.getContext2d(); 
     ImageData imgRes = resCtx.getImageData(0, 0, tw, th); 
     CanvasPixelArray tByteBuffer = imgRes.getData(); 
     // convert float32 array into a UInt8Clamped Array 
     int pxIndex = 0; 
     for (sIndex = 0, tIndex = 0; pxIndex < tw * th; sIndex += 4, tIndex += 4, pxIndex++) { 
      tByteBuffer.set(tIndex, (int)Math.ceil(tBuffer.get(sIndex))); 
      tByteBuffer.set(tIndex + 1, (int)Math.ceil(tBuffer.get(sIndex + 1))); 
      tByteBuffer.set(tIndex + 2, (int)Math.ceil(tBuffer.get(sIndex + 2))); 
      tByteBuffer.set(tIndex + 3, (int)Math.ceil(tBuffer.get(sIndex + 3))); 
     } 
     // writing result to canvas. 
     resCtx.putImageData(imgRes, 0, 0); 

     return resCV.getCanvasElement(); 

    } 

我不知道如何写的语句,比如thit TY = 0 | ty在Java中。我也不确定是否canvas.width(value);转换成canvas.setCoordinateSpaceWidth(value);

编辑:

是|在JS(0 TY +级)的((长)TY +规模)在Java中?

什么是

var sBuffer = cv.getContext('2d').getImageData(0, 0, sw, sh).data 

翻译是CanvasPixelArray

CanvasPixelArray sBuffer = cv.getContext2d().getImageData(0, 0, sw, sh).getData() 

有人可以帮我翻译?

编辑︰事实证明,我的Java代码是非常缓慢的。我无法在开发模式下运行它。在prod模式下,事件比JavaScript代码慢。为什么这个代码更慢?

+2

为什么要将其转换为Java?您可以在GWT中调用Java代码中的JavaScript函数。 – Braj

+0

欲了解更多信息,请看[从Java GWT代码中调用.js文件的Javascript函数](http://stackoverflow.com/questions/11986462/calling-javascript-function-of-js-file-from-java- gwt-code) – Braj

+1

@Braj我知道如何使用JSNI,但我想要纯Java。这样GWT编译可以优化代码。 – confile

回答

0

0 | tY正在将一个JS Number(相当于一个Java double)舍入为一个整数值;相当于Math.floor(tY)(long) tYint对于所有可用double表示的整数值都太小,但在此特定情况下可能会正常)。

canvas.width映射到Canvas#getCoordinateSpaceWidth,你可以在GWT的来源中看到。最后,new Float32Array(n)映射到TypedArrays.createFloat32Array

+0

请参阅我的编辑。 – confile

+0

任何想法,我的编辑? – confile

相关问题