The project uses GWT, but in this case it serves only as a wrapper for JavaScript code that works with canvas . Therefore, I will be equally happy to address both the GWT and JavaScript.

The task is as follows: we have an input image that is uploaded and drawn to the canvas, and this canvas is attached . By clicking we need to apply a graphic filter. To do this, take the input image inputImage , apply a filter to it, and then output the result to another outputImage image. I wrote this code:

 // канвас для Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ изобраТСния Canvas canvas = new Canvas(Document.get().createCanvasElement()); Context2d context2d = canvas.getContext2d(); // элСмСнт Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ изобраТСния ImageElement imageElement = ImageElement.as(inputImage.getElement()); context2d.drawImage(imageElement, 0, 0, width, height, 0, 0, width, height); ImageData data = context2d.getImageData(0, 0, width, height); CanvasPixelArray array = data.getData(); for (int i = 0; i < array.getLength(); i = i + 4) { // примСняСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€, для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° я ΠΏΠ΅Ρ€Π΅Π²ΠΎΠΆΡƒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого int silver = (array.get(i) + array.get(i + 1) + array.get(i + 2)) / 3; array.set(i, silver); array.set(i + 1, silver); array.set(i + 2, silver); } context2d.putImageData(data, 0, 0); outputImage.setUrl(canvas.toDataUrl("image/png")); 

It works great in Chrome and in Safari, but does not work in Mozille and in IE9. At the same time in IE9, an exception falls:

com.google.gwt.core.client.JavaScriptException: (Error): Unknown failure at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript (BrowserChannelServer.java:237) at com.google.gwt.dev.shell. ModuleSpaceOOPHM.doInvoke (ModuleSpaceOOPHM.java:132) at com.google.gwt.dev.shell.ModuleSpace.invokeNative (ModuleSpace.javament61) at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject (ModuleSpace.java: 269) at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject (JavaScriptHost.java:91) at com.google.gwt.canvas.dom.client.ImageData $ .getData $ (ImageData.java)

That is, Internet Explorer 9 swears at the line

 CanvasPixelArray array = data.getData(); 

When you try to modify the code, for example, replacing the CanvasPixelArray pass with a pass directly through ImageData exception in IE does not fall, but the application does not output anything to outputImage .

And in Mozilla:

com.google.gwt.core.clients ) at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke (ModuleSpaceOOPHM.java:132) at com.google.gwt.dev.shell.ModuleSpace.invokeNative (ModuleSpace.java partner61) at com.google.gwt. dev.shell.ModuleSpace.invokeNativeVoid (ModuleSpace.java:289) at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid (JavaScriptHost.java:107) at com.google.gwt.canvas.dom.client.Context2d $ .drawImage $ (Context2d.java)

Mozilla swears at the attempt to output outputImage to the main canvas using the drawImage method.

How can I make this code work?

    1 answer 1

    Do not use the getData() method, it does not work in IE. It is necessary to work with image data through the methods of the ImageData class. Can replace

     CanvasPixelArray array = data.getData(); for (int i = 0; i < array.getLength(); i = i + 4) { // примСняСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€, для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° я ΠΏΠ΅Ρ€Π΅Π²ΠΎΠΆΡƒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого int silver = (array.get(i) + array.get(i + 1) + array.get(i + 2)) / 3; array.set(i, silver); array.set(i + 1, silver); array.set(i + 2, silver); } 

    on

     for (int j = 0; j < data.getHeight(); j++) { for (int i = 0; i < data.getWidth(); i++) { // примСняСм Ρ„ΠΈΠ»ΡŒΡ‚Ρ€, для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° я ΠΏΠ΅Ρ€Π΅Π²ΠΎΠΆΡƒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ сСрого int silver = ((data.getRedAt(i, j) + data.getGreenAt(i, j) + data.getBlueAt(i, j)) / 3 + 128) / 2; data.setRedAt(silver, i, j); data.setGreenAt(silver, i, j); data.setBlueAt(silver, i, j); } } 

    Concerning FF - such an exception falls when the image is not loaded yet. Transfer the code, from where the exception falls, to the onload handler.