package com.akjava.gwt.lib.client.experimental; import static com.google.common.base.Preconditions.checkNotNull; import javax.annotation.Nullable; import com.akjava.gwt.lib.client.CanvasUtils; import com.akjava.gwt.lib.client.ImageElementUtils; import com.akjava.lib.common.utils.ColorUtils; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.canvas.dom.client.ImageData; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.ImageElement; import com.google.gwt.typedarrays.client.Uint8ArrayNative; public class ImageDataUtils { public static Canvas sharedCanvas; private static Canvas getSharedCanvas(){ if(sharedCanvas==null){ sharedCanvas=Canvas.createIfSupported(); } return sharedCanvas; } public static ImageData convertToGrayScale(ImageData data,boolean firstChannelOnly) { for(int y=0;y<data.getHeight();y++){ for(int x=0;x<data.getWidth();x++){ int value=(int) (0.299*data.getRedAt(x, y) + 0.587*data.getGreenAt(x, y) + 0.114*data.getBlueAt(x, y)); data.setRedAt(value, x, y); if(firstChannelOnly){ data.setGreenAt(value, x, y); data.setBlueAt(value, x, y); } } } return data; } public static ImageData createWithSharedCanvas(int w,int h){ return createNoCopyWith(null,w,h); } public static ImageData copyFrom(Canvas canvas){ return canvas.getContext2d().getImageData(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()); } public static ImageData createNoCopyWith(Canvas canvas,int w,int h){ if(canvas==null){ canvas=getSharedCanvas(); } return canvas.getContext2d().createImageData(w, h); } public static ImageData copySizeOnly(Canvas canvas){ return canvas.getContext2d().createImageData(canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight()); } public static ImageData create(@Nullable Canvas canvas,ImageElement element){ if(canvas==null){ canvas=Canvas.createIfSupported(); } ImageElementUtils.copytoCanvas(element, canvas, true); return CanvasUtils.getImageData(canvas, true); } public static void setAlphaAll(ImageData imageData,int alpha){ for(int x=0;x<imageData.getWidth();x++){ for(int y=0;y<imageData.getHeight();y++){ imageData.setAlphaAt(alpha, x, y); } } } public static Uint8ArrayNative crop(ImageData data,int x,int y,int width,int height){ // array=Uint8ArrayNative.create(width*height*4); int values[]=new int[width*height*4]; //LogUtils.log(values.length); for(int i=x;i<x+width;i++){ for(int j=y;j<y+height;j++){ int red=data.getRedAt(i, j); int green=data.getGreenAt(i, j); int blue=data.getBlueAt(i, j); int alpha=data.getAlphaAt(i, j); int offset=((j-y)*width+(i-x))*4; values[offset]=red; values[offset+1]=green; values[offset+2]=blue; values[offset+3]=alpha; /* LogUtils.log(i+"x"+j+"="+red+","+green+","+blue+","+alpha); array.set(offset,red); array.set(offset+1,green); array.set(offset+2,blue); array.set(offset+3,alpha); */ } } return Uint8ArrayNative.create(values); //return values; } public static Uint8ArrayNative cropRedOnly(ImageData data,int x,int y,int width,int height){ // array=Uint8ArrayNative.create(width*height*4); int values[]=new int[width*height*4]; //LogUtils.log(values.length); for(int i=x;i<x+width;i++){ for(int j=y;j<y+height;j++){ int red=data.getRedAt(i, j); //int green=data.getGreenAt(i, j); //int blue=data.getBlueAt(i, j); //int alpha=data.getAlphaAt(i, j); int offset=((j-y)*width+(i-x))*4; values[offset]=red; //values[offset+1]=green; //values[offset+2]=blue; //values[offset+3]=alpha; /* LogUtils.log(i+"x"+j+"="+red+","+green+","+blue+","+alpha); array.set(offset,red); array.set(offset+1,green); array.set(offset+2,blue); array.set(offset+3,alpha); */ } } return Uint8ArrayNative.create(values); //return values; } public static Uint8ArrayNative cropRedOnlyPacked(ImageData data,int x,int y,int width,int height){ // array=Uint8ArrayNative.create(width*height*4); int values[]=new int[width*height]; //LogUtils.log(values.length); for(int i=x;i<x+width;i++){ for(int j=y;j<y+height;j++){ int red=data.getRedAt(i, j); //int green=data.getGreenAt(i, j); //int blue=data.getBlueAt(i, j); //int alpha=data.getAlphaAt(i, j); int offset=((j-y)*width+(i-x)); values[offset]=red; //values[offset+1]=green; //values[offset+2]=blue; //values[offset+3]=alpha; /* LogUtils.log(i+"x"+j+"="+red+","+green+","+blue+","+alpha); array.set(offset,red); array.set(offset+1,green); array.set(offset+2,blue); array.set(offset+3,alpha); */ } } return Uint8ArrayNative.create(values); //return values; } public static ImageData copy(Canvas canvas,ImageData data){ return copy(canvas.getContext2d(),data); } public static ImageData copy(Context2d ctx,ImageData data){ ImageData newData=ctx.createImageData(data); for(int i=0;i<data.getData().getLength();i++){ newData.getData().set(i, data.getData().get(i)); } return newData; } public static ImageData copyFast(Canvas canvas,ImageData data){ return copyFast(canvas.getContext2d(),data); } public static native final ImageData copyFast(Context2d ctx,ImageData src)/*-{ var dst = ctx.createImageData(src.width, src.height); dst.data.set(src.data); return dst; }-*/; public static native final Uint8ArrayNative getUint8(ImageData data)/*-{ return data.data; }-*/; public static native final JavaScriptObject getArrayBuffer(ImageData data)/*-{ return data.data.buffer; }-*/; public static native ImageData set(ImageData imageData,Uint8ArrayNative nativeArray)/*-{ return imageData.data.set(nativeArray); }-*/; public static ImageData setGrayscale(ImageData imageData,Uint8ArrayNative nativeArray,boolean setRGBA){ int w=imageData.getWidth(); for(int i=0;i<nativeArray.length();i++){ int x=i%w; int y=i/w; imageData.setRedAt(nativeArray.get(i), x, y); if(setRGBA){ imageData.setGreenAt(nativeArray.get(i), x, y); imageData.setBlueAt(nativeArray.get(i), x, y); imageData.setAlphaAt(255, x, y); } } return imageData; } public static boolean isSameData(ImageData data1,ImageData data2){ if(data1==data2){ return true; } if(data1.getWidth()!=data2.getWidth() || data1.getHeight()!=data2.getHeight()){ return false; } for(int x=0;x<data1.getWidth();x++){ for(int y=0;y<data1.getHeight();y++){ if(data1.getRedAt(x, y)!=data2.getRedAt(x, y)){ return false; } if(data1.getGreenAt(x, y)!=data2.getGreenAt(x, y)){ return false; } if(data1.getBlueAt(x, y)!=data2.getBlueAt(x, y)){ return false; } if(data1.getAlphaAt(x, y)!=data2.getAlphaAt(x, y)){ return false; } } } return true; } public static void rezieAndImageData(ImageData data,Canvas canvas) { checkNotNull(data,"putImageData:need data"); checkNotNull(canvas,"putImageData:need canvas"); CanvasUtils.setSize(canvas, data.getWidth(), data.getHeight()); putImageData(data, canvas); } public static void putImageData(ImageData data,Canvas canvas) { checkNotNull(data,"putImageData:need data"); checkNotNull(canvas,"putImageData:need canvas"); canvas.getContext2d().putImageData(data, 0, 0); } public static void replaceColor(ImageData data, int oldColor, int newColor) { int[] rgb=ColorUtils.toRGB(oldColor); int[] newrgb=ColorUtils.toRGB(newColor); for(int x=0;x<data.getWidth();x++){ for(int y=0;y<data.getHeight();y++){ if(data.getAlphaAt(x, y)!=255){ // continue; } int r=data.getRedAt(x, y); if(r!=rgb[0]){ continue; } int g=data.getGreenAt(x, y); if(g!=rgb[1]){ continue; } int b=data.getBlueAt(x, y); if(b!=rgb[2]){ continue; } ImageDataUtils.setRGBAt(data,newrgb[0],newrgb[1],newrgb[2],x,y); } } } public static void executeRGBFilter(ImageData data, RGBColorFilter filter) { for(int x=0;x<data.getWidth();x++){ for(int y=0;y<data.getHeight();y++){ int a=data.getAlphaAt(x, y); int r=data.getRedAt(x, y); int g=data.getGreenAt(x, y); int b=data.getBlueAt(x, y); int[] rgb=filter.filterRGB(r, g, b, a); ImageDataUtils.setRGBAt(data,rgb[0],rgb[1],rgb[2],x,y); } } } public static interface RGBColorFilter{ public int[] filterRGB(int r,int g,int b,int a); } public static void setRGBAt(ImageData data, int color, int x, int y) { int[] rgb=ColorUtils.toRGB(color); data.setRedAt(rgb[0], x, y); data.setGreenAt(rgb[1], x, y); data.setBlueAt(rgb[2], x, y); } public static void setRGBAt(ImageData data, int r,int g,int b, int x, int y) { data.setRedAt(r, x, y); data.setGreenAt(g, x, y); data.setBlueAt(b, x, y); } /** * var dst = ctx.createImageData(src.width, src.height); dst.data.set(src.data); return dst; * */ }