Project

General

Profile

chrome_copy_image_1.txt

Sergey Ivanovskiy, 01/11/2016 12:41 PM

Download (5.03 KB)

 
1
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js'
2
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js	2015-12-16 13:35:36 +0000
3
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js	2016-01-11 17:33:23 +0000
4
@@ -20,6 +20,8 @@
5
 ** 005 SBI 20151205 Changed to adjust clipping regions according to a new origin.
6
 ** 006 SBI 20151216 Changed to work around that the Chrome's implementation of getImageData
7
 **                  rounds function parameters.
8
+**     SBI 20160111 Rewrite the copy of the target image taking into account the Chrome's
9
+**                  getImageData implementation.
10
 */
11
 
12
 "use strict";
13
@@ -432,15 +434,7 @@
14
    {
15
       var w = imageData.width;
16
       var h = imageData.height;
17
-      var screenShot;
18
-      if (p2j.isChrome)
19
-      {
20
-         screenShot = this.ctx.getImageData(Math.round(x), Math.round(y), w, h);
21
-      }
22
-      else
23
-      {
24
-         screenShot = this.ctx.getImageData(x, y, w, h);
25
-      }
26
+      var screenShot = this.ctx.getImageData(x, y, w, h);
27
       var pixelsInBytes = 4 * w * h;
28
       for (var i = 0; i < pixelsInBytes; i += 4)
29
       {
30
@@ -791,19 +785,79 @@
31
     * Pixels must be returned as non-premultiplied alpha values according to:
32
     * http://www.w3.org/TR/2dcontext/#pixel-manipulation
33
     */
34
-   var img;
35
+   var img = ctx.getImageData(xo, yo, width, height);
36
+   var data = img.data;
37
    if (p2j.isChrome)
38
    {
39
-      img = ctx.getImageData(Math.round(xo), Math.round(yo), width, height);
40
+      copyImage(img, data, imgData, width, height, imgDataOffset);
41
    }
42
    else
43
    {
44
-      img = ctx.getImageData(xo, yo, width, height);
45
-   }
46
-   var data = img.data;
47
-   var pixelsInBytes = width * height * 4;
48
+      // optimized version of copy image
49
+      var pixelsInBytes = width * height * 4;
50
+      var offset = imgDataOffset;
51
+      for (var p = 0; p < pixelsInBytes; p += 4, offset += 4)
52
+      {
53
+         var alpha = imgData[offset + 3];
54
+         var beta = 256 - alpha;
55
+         if (alpha == 255)
56
+         {
57
+            /** server sends non-premultiplied image data */
58
+            data[p]     = imgData[offset];
59
+            data[p + 1] = imgData[offset + 1];
60
+            data[p + 2] = imgData[offset + 2];
61
+            data[p + 3] = imgData[offset + 3];
62
+         }
63
+         else if (alpha > 0)
64
+         {
65
+            /** server sends non-premultiplied image data */
66
+            data[p]     = (imgData[offset]     * alpha + data[p]     * beta) >> 8;
67
+            data[p + 1] = (imgData[offset + 1] * alpha + data[p + 1] * beta) >> 8;
68
+            data[p + 2] = (imgData[offset + 2] * alpha + data[p + 2] * beta) >> 8;
69
+            data[p + 3] = (imgData[offset + 3] * alpha + data[p + 3] * beta) >> 8;
70
+         };
71
+      };
72
+   }
73
+   var deltaX = xa - xo;
74
+   var deltaY = ya - yo;
75
+   if (this.compositeModeOn)
76
+   {
77
+      this.applyCompositeMode(img, xo, yo);
78
+   }
79
+   this.ctx.putImageData(img, xo, yo, deltaX, deltaY, xb - xa, yb - ya);
80
+};
81
+
82
+/**
83
+ * Copies a downloaded image encodded as an rgba byte array provided with its width and its height
84
+ * to the screen image given by its own width and height taking into account the coppied image
85
+ * alpha channel and places it at the zero coordinates relative to the screen image.
86
+ * 
87
+ * @param    {ImageData} img
88
+ *           The screen image data
89
+ * @param    {Uint8ClampedArray} data
90
+ *           The screen image rgba byte array. 
91
+ * @param    {Array} imgData
92
+ *           The rgba byte array of the coppied image.
93
+ * @param    {Number} width
94
+ *           The coppied image width.
95
+ * @param    {Number} height
96
+ *           The coppied image height.
97
+ * @param    {Number} imgDataOffset
98
+ *           The coppied image data offset from the 0-index of its data array, imgData.
99
+ * 
100
+ * @return   {Uint8ClampedArray}
101
+ *           Returns the modified screen image data array with the target image.
102
+ *  
103
+ */
104
+function copyImage(img, data, imgData, width, height, imgDataOffset)
105
+{
106
+   var awidth  = img.width;
107
+   var aheight = img.height;
108
+   var x = 0;
109
+   var y = 0;
110
+   var pixelsInBytes = awidth * aheight * 4;
111
    var offset = imgDataOffset;
112
-   for (var p = 0; p < pixelsInBytes; p += 4, offset += 4)
113
+   for (var p = 0; p < pixelsInBytes; offset += 4)
114
    {
115
       var alpha = imgData[offset + 3];
116
       var beta = 256 - alpha;
117
@@ -823,14 +877,22 @@
118
          data[p + 2] = (imgData[offset + 2] * alpha + data[p + 2] * beta) >> 8;
119
          data[p + 3] = (imgData[offset + 3] * alpha + data[p + 3] * beta) >> 8;
120
       };
121
+      x++;
122
+      // p = (y * awidth + x) * 4
123
+      // p1 - p0 = [(y1 - y0) * awidth + (x1 - x0)] * 4 = 4 or 4 * (awidth - width) + 4 
124
+      if (x == width)
125
+      {
126
+         y++;
127
+         x = 0;
128
+         p += ((awidth - width + 1) * 4);
129
+      }
130
+      else
131
+      {
132
+         p += 4; 
133
+      }
134
    };
135
-   var deltaX = xa - xo;
136
-   var deltaY = ya - yo;
137
-   if (this.compositeModeOn)
138
-   {
139
-      this.applyCompositeMode(img, xo, yo);
140
-   }
141
-   this.ctx.putImageData(img, xo, yo, deltaX, deltaY, xb - xa, yb - ya);
142
+   
143
+   return data;
144
 };
145
 
146
 /**
147