Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6053399
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T08:02:09+00:00 2026-05-23T08:02:09+00:00

i have an app that places a fisheye distortion effect on a bitmap. to

  • 0

i have an app that places a fisheye distortion effect on a bitmap. to create the distortion i must loop through the entire bitmap checking whether a given pixel falls with a circle bounds. if it does then i manipulate that pixel. This process is labour intensive and takes upto 50 secs. i was thinking of different ways to do this so i don’t have to loop through the whole bitmap to apply the effect.
one idea i have is to draw the bitmap first and display it. then create a second bitmap overlay which only has the effect on. i could then overlay the second bitmap on the first. i’m just trying to think of ways in which i can apply this effect without looping through as many pixels to speed things up. i’ll post the distortion class. thanks.

.

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";
    long getRadXStart = 0;
    long getRadXEnd = 0;
    long startSample = 0;
    long endSample = 0;
    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 ");
        Debug.startMethodTracing("barrel");

        //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
       // 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;
        //  Log.e(TAG, "***********xscale ="+xscale);
          yscale = (height-yshift-yshift_2)/height;
        //  Log.e(TAG, "***********yscale ="+yscale);
        //  Log.e(TAG, "***********filter.barrel() 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;
          long startLoop = System.currentTimeMillis();
          for(int j=0;j<dst.getHeight();j++){
              for(int i=0;i<dst.getWidth();i++){
                 origPixel= input.getPixel(i,j);
                 getRadXStart = System.currentTimeMillis();
                float x = getRadialX((float)j,(float)i,centerX,centerY,k);
                getRadXEnd= System.currentTimeMillis();

                float y = getRadialY((float)j,(float)i,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) ) ) <= 150 ){
                if(  Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) )  <= 22500 ){
                dst.setPixel(i, j, color);
                }else{
                    dst.setPixel(i,j,origPixel);
                }
              }
            }
          long endLoop = System.currentTimeMillis();
          long loopDuration = endLoop - startLoop;
          long radXDuration = getRadXEnd - getRadXStart;
          long sampleDur = endSample - startSample;

          Log.e(TAG, "sample method took "+sampleDur+"ms");
          Log.e(TAG, "getRadialX took "+radXDuration+"ms");
          Log.e(TAG, "loop took "+loopDuration+"ms");

        //  Log.e(TAG, "***********filter.barrel()  looped through bm about to return dst bm");
          Debug.stopMethodTracing();
        return dst;

    }

    void sampleImage(Bitmap arr, float idx0, float idx1)
    {
         startSample = System.currentTimeMillis();
       // 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));

      endSample = System.currentTimeMillis();
    }

    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

.

[update]
Hi, i’ve not watched all the vid cos i’ve only so much data allowance on dongle so going to wait till at work to watch it. I’ve modified the code to the one below. This stores the pixel data in an int array, so there’s no call to dst.setPixel. it’s still very slow(14 secs on 3.2MP camera) not at all like a few seconds as your code does. can you share that code or tell me if this is not what you meant. thanks Matt.

int origPixel = 0;
          int []arr = new int[input.getWidth()*input.getHeight()];
          int color = 0;

          int p = 0;
          int i = 0;
          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) )  <= 22500 ){
                //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;

                }
              }
            }



        //  Log.e(TAG, "***********filter.barrel()  looped through bm about to return dst bm");
          Debug.stopMethodTracing();
         Bitmap dst2 = Bitmap.createBitmap(arr,width,height,input.getConfig());
        return dst2;

    }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T08:02:10+00:00Added an answer on May 23, 2026 at 8:02 am

    I bet you’d cut down considerably on your execution time if you eliminated the call to dst.setPixel inside your inner loop. Instead of operating on the Bitmaps inside your loop, stuff the values into integer arrays during your loop and call setPixels at the end passing in the array.

    I have image manipulation code that can loop through an entire 2MP image in a few seconds.

    On older Android api’s (I believe earlier than 2.3, but it might even include 2.3), the actual image data does not reside in the managed heap so there’s probably some expensive operation going on to find the actual location of the bits you’re overwriting in the call to setPixel. The source of my information is the Google I/O 2011 video on memory management in Android. If you’re doing this kind of work in Android, it’s a must watch:

    http://www.youtube.com/watch?v=_CruQY55HOk

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've an app that takes a camera image and places a fisheye distortion effect
I have an app that places a distortion on a bitmap. i'm trying to
i've an app that loops through a bitmap and places a distortion on it.
I have a background that i put in my app and there are places
I have an ASP.NET web app that places several string data into an object
I'm writing an app that stores the location of the places you have been
I have a Delphi app that places the computer into screensave using hWnd :=
I have a delphi app that logs data from various places and writes the
have an app that finds your GPS location successfully, but I need to be
Have an app that has listings - think classified ads - and each listing

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.