Is the circular fisheye distortion rotated 270 degrees clockwise or 90 degrees counterclockwise until distortion?

I have an application that distorts a circle in a bitmap with fisheye distortion. the circle rotates 180 degrees and is also distorted. Any ideas? I don’t know why in the filter class. thanks Matt.

import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import com.tecmark.HorizontalSlider.OnProgressChangeListener; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuff.Mode; import android.graphics.Shader.TileMode; import android.os.Environment; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class TouchView extends View{ private File tempFile; private byte[] imageArray; private Bitmap bgr; private Bitmap bm; private Bitmap bgr2 = null;; private Paint pTouch; private int centreX = 1; private int centreY = 1; private int radius = 50; private int Progress; private static final String TAG = "*********TouchView"; private Filters f = null; public TouchView(Context context) { super(context); // TouchView(context, null); } public TouchView(Context context, AttributeSet attr) { super(context,attr); tempFile = new File(Environment.getExternalStorageDirectory(). getAbsolutePath() + "/"+"image.jpg"); imageArray = new byte[(int)tempFile.length()]; try{ InputStream is = new FileInputStream(tempFile); BufferedInputStream bis = new BufferedInputStream(is); DataInputStream dis = new DataInputStream(bis); int i = 0; while (dis.available() > 0) { imageArray[i] = dis.readByte(); i++; } dis.close(); } catch (Exception e) { e.printStackTrace(); } BitmapFactory.Options bfo = new BitmapFactory.Options(); bfo.inSampleSize = 1; bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo); bgr = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); bgr = bm.copy(bm.getConfig(), true); bgr2 = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig()); f = new Filters(); //bgr2 = f.barrel(bgr,0.00022F); pTouch = new Paint(Paint.ANTI_ALIAS_FLAG); pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)); pTouch.setColor(Color.TRANSPARENT); pTouch.setStyle(Paint.Style.STROKE); }// end of touchView constructor public void findCirclePixels(){ /* for (int i=centreX-50; i < centreX+50; ++i) { for (int y=centreY-50; y <centreY+50 ; ++y) { if( Math.sqrt( Math.pow(i - centreX, 2) + ( Math.pow(y - centreY, 2) ) ) <= radius ){ bgr.setPixel(i,y,Color.rgb(Progress+50,Progress,Progress+100)); } } }*/ float prog = (float)Progress/2000000; bgr2 = f.barrel(bgr,prog); }// end of changePixel() @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: { centreX = (int) ev.getX(); centreY = (int) ev.getY(); findCirclePixels(); invalidate(); break; } case MotionEvent.ACTION_MOVE: { centreX = (int) ev.getX(); centreY = (int) ev.getY(); findCirclePixels(); invalidate(); break; } case MotionEvent.ACTION_UP: break; } return true; }//end of onTouchEvent public void initSlider(final HorizontalSlider slider) { Log.e(TAG, "******setting up slider*********** "); slider.setOnProgressChangeListener(changeListener); } private OnProgressChangeListener changeListener = new OnProgressChangeListener() { @Override public void onProgressChanged(View v, int progress) { // TODO Auto-generated method stub setProgress(progress); Log.e(TAG, "***********progress = "+Progress); } }; @Override public void onDraw(Canvas canvas){ super.onDraw(canvas); canvas.drawBitmap(bgr2, 0, 0, null); canvas.drawCircle(centreX, centreY, radius,pTouch); }//end of onDraw protected void setProgress(int progress2) { this.Progress = progress2; findCirclePixels(); invalidate(); } } 

.

 import android.graphics.Bitmap; import android.util.Log; class Filters{ float xscale; float yscale; float xshift; float yshift; int [] s; private String TAG = "Filters"; public Filters(){ Log.e(TAG, "***********inside constructor"); } public Bitmap barrel (Bitmap input, float k){ Log.e(TAG, "***********inside barrel method "); float centerX=input.getWidth()/2; //center of distortion float centerY=input.getHeight()/2; int width = input.getWidth(); //image bounds int height = input.getHeight(); Bitmap dst = Bitmap.createBitmap(width, height,input.getConfig() ); //output pic Log.e(TAG, "***********dst bitmap created "); xshift = calc_shift(0,centerX-1,centerX,k); float newcenterX = width-centerX; float xshift_2 = calc_shift(0,newcenterX-1,newcenterX,k); yshift = calc_shift(0,centerY-1,centerY,k); float newcenterY = height-centerY; float yshift_2 = calc_shift(0,newcenterY-1,newcenterY,k); xscale = (width-xshift-xshift_2)/width; yscale = (height-yshift-yshift_2)/height; Log.e(TAG, "***********about to loop through bm"); /*for(int j=0;j<dst.getHeight();j++){ for(int i=0;i<dst.getWidth();i++){ float x = getRadialX((float)i,(float)j,centerX,centerY,k); float y = getRadialY((float)i,(float)j,centerX,centerY,k); sampleImage(input,x,y); int color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff); // System.out.print(i+" "+j+" \\"); dst.setPixel(i, j, color); } }*/ int origPixel; for(int j=0;j<dst.getHeight();j++){ for(int i=0;i<dst.getWidth();i++){ origPixel= input.getPixel(i,j); float x = getRadialX((float)i,(float)j,centerX,centerY,k); float y = getRadialY((float)i,(float)j,centerX,centerY,k); sampleImage(input,x,y); int color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff); // System.out.print(i+" "+j+" \\"); if( Math.sqrt( Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) ) ) <= 85 ){ dst.setPixel(i, j, color); }else{ dst.setPixel(i,j,origPixel); } } } return dst; } void sampleImage(Bitmap arr, float idx0, float idx1) { s = new int [4]; if(idx0<0 || idx1<0 || idx0>(arr.getHeight()-1) || idx1>(arr.getWidth()-1)){ s[0]=0; s[1]=0; s[2]=0; s[3]=0; return; } float idx0_fl=(float) Math.floor(idx0); float idx0_cl=(float) Math.ceil(idx0); float idx1_fl=(float) Math.floor(idx1); float idx1_cl=(float) Math.ceil(idx1); int [] s1 = getARGB(arr,(int)idx0_fl,(int)idx1_fl); int [] s2 = getARGB(arr,(int)idx0_fl,(int)idx1_cl); int [] s3 = getARGB(arr,(int)idx0_cl,(int)idx1_cl); int [] s4 = getARGB(arr,(int)idx0_cl,(int)idx1_fl); float x = idx0 - idx0_fl; float y = idx1 - idx1_fl; s[0]= (int) (s1[0]*(1-x)*(1-y) + s2[0]*(1-x)*y + s3[0]*x*y + s4[0]*x*(1-y)); s[1]= (int) (s1[1]*(1-x)*(1-y) + s2[1]*(1-x)*y + s3[1]*x*y + s4[1]*x*(1-y)); s[2]= (int) (s1[2]*(1-x)*(1-y) + s2[2]*(1-x)*y + s3[2]*x*y + s4[2]*x*(1-y)); s[3]= (int) (s1[3]*(1-x)*(1-y) + s2[3]*(1-x)*y + s3[3]*x*y + s4[3]*x*(1-y)); } int [] getARGB(Bitmap buf,int x, int y){ int rgb = buf.getPixel(y, x); // Returns by default ARGB. int [] scalar = new int[4]; scalar[0] = (rgb >>> 24) & 0xFF; scalar[1] = (rgb >>> 16) & 0xFF; scalar[2] = (rgb >>> 8) & 0xFF; scalar[3] = (rgb >>> 0) & 0xFF; return scalar; } float getRadialX(float x,float y,float cx,float cy,float k){ x = (x*xscale+xshift); y = (y*yscale+yshift); float res = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy))); return res; } float getRadialY(float x,float y,float cx,float cy,float k){ x = (x*xscale+xshift); y = (y*yscale+yshift); float res = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy))); return res; } float thresh = 1; float calc_shift(float x1,float x2,float cx,float k){ float x3 = (float)(x1+(x2-x1)*0.5); float res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx))); float res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx))); if(res1>-thresh && res1 < thresh) return x1; if(res3<0){ return calc_shift(x3,x2,cx,k); } else{ return calc_shift(x1,x3,cx,k); } } } 
+4
source share
3 answers

Are you sure that it does not rotate 90 ° and does not bounce? This can be caused by transposing the X and Y axes. For example, I see that you are calling buf.getPixel(y, x) , despite the Bitmap getPixel accepting x and y instead of y and x.

+1
source

Just guess, but since a 180 degree rotation around (0,0) is a reflection at x = 0 plus a reflection at y = 0, I wonder if your xscale and yscale negative. I did not follow the logic more deeply, but perhaps by stepping into the debugger or registering these values, you could throw something away.

0
source

@Thiago updated code here as promised. it runs @ for about 15 seconds to scroll the bitmap. I think first display the camera image and then use the 2nd bitmap invoice on top. overlay i could reduce the size of the effect and then put it on top of the original image. this way I will only loop around 1/3 of the pixels. I'm not sure if this will work :) Play with it.

.

 import android.graphics.Bitmap; import android.os.Debug; import android.util.Log; class Filters{ private float xscale; private float yscale; private float xshift; private float yshift; private int [] s; private int [] scalar; private int [] s1; private int [] s2; private int [] s3; private int [] s4; private String TAG = "Filters"; public Filters(){ Log.e(TAG, "***********inside filter constructor"); s = new int[4]; scalar = new int[4]; s1 = new int[4]; s2 = new int[4]; s3 = new int[4]; s4 = new int[4]; } public Bitmap barrel (Bitmap input, float k,float cenx, float ceny){ //Log.e(TAG, "***********INSIDE BARREL METHOD "); //float centerX=input.getWidth()/2; //center of distortion //float centerY=input.getHeight()/2; float centerX=cenx; float centerY=ceny; int width = input.getWidth(); //image bounds int height = input.getHeight(); Bitmap dst = Bitmap.createBitmap(width, height,input.getConfig() ); //output pic xshift = calc_shift(0,centerX-1,centerX,k); float newcenterX = width-centerX; float xshift_2 = calc_shift(0,newcenterX-1,newcenterX,k); yshift = calc_shift(0,centerY-1,centerY,k); float newcenterY = height-centerY; float yshift_2 = calc_shift(0,newcenterY-1,newcenterY,k); xscale = (width-xshift-xshift_2)/width; yscale = (height-yshift-yshift_2)/height; /*for(int j=0;j<dst.getHeight();j++){ for(int i=0;i<dst.getWidth();i++){ float x = getRadialX((float)i,(float)j,centerX,centerY,k); float y = getRadialY((float)i,(float)j,centerX,centerY,k); sampleImage(input,x,y); int color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff); // System.out.print(i+" "+j+" \\"); dst.setPixel(i, j, color); } }*/ int origPixel = 0; int []arr = new int[input.getWidth()*input.getHeight()]; int color = 0; int p = 0; int i = 0; long startLoop = System.currentTimeMillis(); for(int j=0;j<dst.getHeight();j++){ for( i=0;i<dst.getWidth();i++,p++){ origPixel= input.getPixel(i,j); float x = getRadialX((float)j,(float)i,centerX,centerY,k); float y = getRadialY((float)j,(float)i,centerX,centerY,k); sampleImage(input,x,y); color = ((s[1]&0x0ff)<<16)|((s[2]&0x0ff)<<8)|(s[3]&0x0ff); // System.out.print(i+" "+j+" \\"); //if( Math.sqrt( Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) ) ) <= 150 ){ if( Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) ) <= 12500 ){ //dst.setPixel(i, j, color); arr[p]=color; //Log.e(TAG, "***********arr = " +arr[i]+" i = "+i); }else{ //dst.setPixel(i,j,origPixel); arr[p]=origPixel; } } } long endLoop = System.currentTimeMillis(); long dur = endLoop - startLoop; Log.e(TAG, "loop took "+dur+"ms"); Bitmap dst2 = Bitmap.createBitmap(arr,width,height,input.getConfig()); return dst2; }// end of barrel() void sampleImage(Bitmap arr, float idx0, float idx1) { // s = new int [4]; if(idx0<0 || idx1<0 || idx0>(arr.getHeight()-1) || idx1>(arr.getWidth()-1)){ s[0]=0; s[1]=0; s[2]=0; s[3]=0; return; } float idx0_fl=(float) Math.floor(idx0); float idx0_cl=(float) Math.ceil(idx0); float idx1_fl=(float) Math.floor(idx1); float idx1_cl=(float) Math.ceil(idx1); /* float idx0_fl=idx0; float idx0_cl=idx0; float idx1_fl=idx1; float idx1_cl=idx1;*/ /* int [] s1 = getARGB(arr,(int)idx0_fl,(int)idx1_fl); int [] s2 = getARGB(arr,(int)idx0_fl,(int)idx1_cl); int [] s3 = getARGB(arr,(int)idx0_cl,(int)idx1_cl); int [] s4 = getARGB(arr,(int)idx0_cl,(int)idx1_fl);*/ s1 = getARGB(arr,(int)idx0_fl,(int)idx1_fl); s2 = getARGB(arr,(int)idx0_fl,(int)idx1_cl); s3 = getARGB(arr,(int)idx0_cl,(int)idx1_cl); s4 = getARGB(arr,(int)idx0_cl,(int)idx1_fl); float x = idx0 - idx0_fl; float y = idx1 - idx1_fl; s[0]= (int) (s1[0]*(1-x)*(1-y) + s2[0]*(1-x)*y + s3[0]*x*y + s4[0]*x*(1-y)); s[1]= (int) (s1[1]*(1-x)*(1-y) + s2[1]*(1-x)*y + s3[1]*x*y + s4[1]*x*(1-y)); s[2]= (int) (s1[2]*(1-x)*(1-y) + s2[2]*(1-x)*y + s3[2]*x*y + s4[2]*x*(1-y)); s[3]= (int) (s1[3]*(1-x)*(1-y) + s2[3]*(1-x)*y + s3[3]*x*y + s4[3]*x*(1-y)); } int [] getARGB(Bitmap buf,int x, int y){ int rgb = buf.getPixel(y, x); // Returns by default ARGB. // int [] scalar = new int[4]; scalar[0] = (rgb >>> 24) & 0xFF; scalar[1] = (rgb >>> 16) & 0xFF; scalar[2] = (rgb >>> 8) & 0xFF; scalar[3] = (rgb >>> 0) & 0xFF; return scalar; } float getRadialX(float x,float y,float cx,float cy,float k){ x = (x*xscale+xshift); y = (y*yscale+yshift); float res = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy))); return res; } float getRadialY(float x,float y,float cx,float cy,float k){ x = (x*xscale+xshift); y = (y*yscale+yshift); float res = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy))); return res; } float thresh = 1; float calc_shift(float x1,float x2,float cx,float k){ float x3 = (float)(x1+(x2-x1)*0.5); float res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx))); float res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx))); if(res1>-thresh && res1 < thresh) return x1; if(res3<0){ return calc_shift(x3,x2,cx,k); } else{ return calc_shift(x1,x3,cx,k); } } }// end of filters class 
0
source

All Articles