如何通过openCV模拟鱼眼镜头效果?

0pc*_*pcl 7 opencv fisheye simulate radial distortion

我正在寻找创建鱼眼镜头效果的方法,查看openCV的文档,看起来它包含像鱼眼这样的径向扭曲的相机校准功能.是否可以通过openCV模拟鱼眼失真?

如果有可能通过openCV来做,与openGL相比,哪一个会产生更好的结果?谢谢.

eli*_*jah 14

我使用opencv 创建了这个应用程序.这是你指的效果吗?我基本上编码维基百科的"失真(光学)"上显示的公式我可以根据需要显示代码

更新:好的,所以下面是使用opencv用c ++编写的实际代码(没有记录,所以随意请求解释):程序收到以下参数作为输入:输入图像 | | 输出图像 | | K控制失真量(通常尝试值约为0.001) | | 失真中心的x坐标 | | 扭曲中心的y坐标 |

所以程序的症结是双环路迭代的结果的图像上逐像素和使用该公式为径向畸变(这是方式图像变形通常完成查找的输入图像中的匹配像素-也许与直觉相反通过从输出到输入的反投影).有一些细微之处与输出图像的比例有关(在这个程序中,生成的图像与输入的大小相同),除非你想了解更多细节,否则我不会深入了解它.享受.

    #include <cv.h>
    #include <highgui.h>
    #include <math.h>
    #include <unistd.h>
    #include <getopt.h>
    #include <iostream>


    void sampleImage(const IplImage* arr, float idx0, float idx1, CvScalar& res)
    {
      if(idx0<0 || idx1<0 || idx0>(cvGetSize(arr).height-1) || idx1>(cvGetSize(arr).width-1)){
        res.val[0]=0;
        res.val[1]=0;
        res.val[2]=0;
        res.val[3]=0;
        return;
      }
      float idx0_fl=floor(idx0);
      float idx0_cl=ceil(idx0);
      float idx1_fl=floor(idx1);
      float idx1_cl=ceil(idx1);

      CvScalar s1=cvGet2D(arr,(int)idx0_fl,(int)idx1_fl);
      CvScalar s2=cvGet2D(arr,(int)idx0_fl,(int)idx1_cl);
      CvScalar s3=cvGet2D(arr,(int)idx0_cl,(int)idx1_cl);
      CvScalar s4=cvGet2D(arr,(int)idx0_cl,(int)idx1_fl);
      float x = idx0 - idx0_fl;
      float y = idx1 - idx1_fl;
      res.val[0]= s1.val[0]*(1-x)*(1-y) + s2.val[0]*(1-x)*y + s3.val[0]*x*y + s4.val[0]*x*(1-y);
      res.val[1]= s1.val[1]*(1-x)*(1-y) + s2.val[1]*(1-x)*y + s3.val[1]*x*y + s4.val[1]*x*(1-y);
      res.val[2]= s1.val[2]*(1-x)*(1-y) + s2.val[2]*(1-x)*y + s3.val[2]*x*y + s4.val[2]*x*(1-y);
      res.val[3]= s1.val[3]*(1-x)*(1-y) + s2.val[3]*(1-x)*y + s3.val[3]*x*y + s4.val[3]*x*(1-y);
    }

    float xscale;
    float yscale;
    float xshift;
    float yshift;

    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 = 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)));

      //  std::cerr<<"x1: "<<x1<<" - "<<res1<<" x3: "<<x3<<" - "<<res3<<std::endl;

      if(res1>-thresh and res1 < thresh)
        return x1;
      if(res3<0){
        return calc_shift(x3,x2,cx,k);
      }
      else{
        return calc_shift(x1,x3,cx,k);
      }
    }

    int main(int argc, char** argv)
    {
      IplImage* src = cvLoadImage( argv[1], 1 );
      IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
      IplImage* dst2 = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
      float K=atof(argv[3]);
      float centerX=atoi(argv[4]);
      float centerY=atoi(argv[5]);
      int width = cvGetSize(src).width;
      int height = cvGetSize(src).height;

      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);
      //  scale = (centerX-xshift)/centerX;
      xscale = (width-xshift-xshift_2)/width;
      yscale = (height-yshift-yshift_2)/height;

      std::cerr<<xshift<<" "<<yshift<<" "<<xscale<<" "<<yscale<<std::endl;
      std::cerr<<cvGetSize(src).height<<std::endl;
      std::cerr<<cvGetSize(src).width<<std::endl;

      for(int j=0;j<cvGetSize(dst).height;j++){
        for(int i=0;i<cvGetSize(dst).width;i++){
          CvScalar s;
          float x = getRadialX((float)i,(float)j,centerX,centerY,K);
          float y = getRadialY((float)i,(float)j,centerX,centerY,K);
          sampleImage(src,y,x,s);
          cvSet2D(dst,j,i,s);

        }
      }
    #if 0
      cvNamedWindow( "Source1", 1 );
      cvShowImage( "Source1", dst);
      cvWaitKey(0);
    #endif

      cvSaveImage(argv[2],dst,0);

    #if 0
      for(int j=0;j<cvGetSize(src).height;j++){
        for(int i=0;i<cvGetSize(src).width;i++){
          CvScalar s;
          sampleImage(src,j+0.25,i+0.25,s);
          cvSet2D(dst,j,i,s);
        }
      }

      cvNamedWindow( "Source1", 1 );
      cvShowImage( "Source1", src);
      cvWaitKey(0);

    #endif  

}
Run Code Online (Sandbox Code Playgroud)


tur*_*boy 5

感谢上面的2代码.我在Java中修改了上述转录代码,使用Bitmaps而不是BufferedImage.这使得代码可以在Android上运行(不支持AWT).我还使效果只是操纵圆圈中的像素而不是整个位图,这给出了鱼眼"镜头"效果.希望这可以帮助任何Android开发人员.

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; // the pixel in orig image

          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+" \\");


// check whether a pixel is within the circle bounds of 150

                if( Math.sqrt( Math.pow(i - centerX, 2) + ( Math.pow(j - centerY, 2) ) ) <= 150 ){
                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);
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

.

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Debug;
import android.util.Log;

public class MultiRuntimeProcessorFilter {



    private static final String TAG = "mrpf";
    private int x = 0;
    private Bitmap input = null;
    private int radius;


    public void createBitmapSections(int nOp, int[] sections){

        int processors = nOp;
        int jMax = input.getHeight();
        int aSectionSize = (int) Math.ceil(jMax/processors);
        Log.e(TAG, "++++++++++ sections size = "+aSectionSize);


        int k = 0;
        for(int h=0; h<processors+1; h++){

                sections[h] = k;
                k+= aSectionSize;



        }
    }// end of createBitmapSections()



    @SuppressWarnings("unchecked")
    public Bitmap barrel (Bitmap input, float k, int r){
          this.radius = r;
          this.input = input;
          int []arr = new int[input.getWidth()*input.getHeight()];


          Log.e(TAG, "bitmap height = "+input.getHeight()); 




          int nrOfProcessors = Runtime.getRuntime().availableProcessors();
          Log.e(TAG, "no of processors = "+nrOfProcessors);

          int[] sections = new int[nrOfProcessors+1];


          createBitmapSections(nrOfProcessors,sections);
          ExecutorService threadPool = Executors.newFixedThreadPool(nrOfProcessors);

          for(int g=0; g<sections.length;g++){
              Log.e(TAG, "++++++++++ sections= "+sections[g]);
          }

         // ExecutorService threadPool = Executors.newFixedThreadPool(nrOfProcessors);

          Object[] task = new Object[nrOfProcessors];

          for(int z = 0; z < nrOfProcessors; z++){
             task[z]  = (FutureTask<PartialResult>) threadPool.submit(new PartialProcessing(sections[z], sections[z+1] - 1, input, k));  
             Log.e(TAG, "++++++++++ task"+z+"= "+task[z].toString()); 
          }

         PartialResult[] results = new PartialResult[nrOfProcessors];

         try{
              for(int t = 0; t < nrOfProcessors; t++){

                  results[t] = ((FutureTask<PartialResult>) task[t]).get();

                  results[t].fill(arr);
              }

          }catch(Exception e){
              e.printStackTrace();
          }

          Bitmap dst2 = Bitmap.createBitmap(arr,input.getWidth(),input.getHeight(),input.getConfig());


        return dst2;


        }//end of barrel()




    public class PartialResult {
           int startP;
           int endP;
           int[] storedValues;

           public PartialResult(int startp, int endp, Bitmap input){

               this.startP = startp;
               this.endP = endp;
               this.storedValues = new int[input.getWidth()*input.getHeight()];


           }

           public void addValue(int p, int result) {
                 storedValues[p] = result;

           }

           public void fill(int[] arr) {



              for (int p = startP; p < endP; p++){
                  for(int b=0;b<radius;b++,x++)
                 arr[x] = storedValues[x];

              } 
              Log.e(TAG, "++++++++++ x ="+x);
              }

           }//end of partialResult




    public class PartialProcessing implements Callable<PartialResult> {
        int startJ;
        int endJ;


        private int[] scalar;
        private float xscale;
        private float yscale;
        private float xshift;
        private float yshift;
        private float thresh = 1;
        private int [] s1;
        private int [] s2;
        private int [] s3;
        private int [] s4;
        private int [] s;
        private Bitmap input;
        private float k;



        public PartialProcessing(int startj, int endj, Bitmap input, float k) {

            this.startJ = startj;
            this.endJ = endj;
            this.input = input;
            this.k = k;

            s = new int[4];
            scalar = new int[4];
            s1 = new int[4];
            s2 = new int[4];
            s3 = new int[4];
            s4 = new int[4];

        }

        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 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);
            }
          }


          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);



             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));


          }



        @Override public PartialResult call() { 

             PartialResult partialResult = new PartialResult(startJ, endJ,input);

             float centerX=input.getWidth()/2; //center of distortion
             float centerY=input.getHeight()/2;



             int width = input.getWidth(); //image bounds
             int height = input.getHeight();



              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;


            int p = startJ*radius; 
            int origPixel = 0;
            int color = 0;
            int i;

            for (int j = startJ; j <  endJ; j++){

                for ( i = 0; i < width; 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);
            //Log.e(TAG, "radius = "+radius);

             if(((i-centerX)*(i-centerX) + (j-centerY)*(j-centerY)) <= radius*(radius/4)){

                                 partialResult.addValue(p, color);


            }else{


                partialResult.addValue(p, origPixel);



            }

                }//end of inner for

        }//end of outer for

            return partialResult;
    }//end of call


}// end of partialprocessing

}//end of MultiProcesorFilter
Run Code Online (Sandbox Code Playgroud)

@And_Dev承诺

下面是让用户触摸co-ords然后在选定区域调用过滤器的视图.所选区域是绳索,例如圆心和半径(圆圈).代码执行两次作为隆胸应用程序:)只需注释掉Horizo​​ntalSlider代码,因为你不需要这个.

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.tecmark.HorizontalSlider.OnProgressChangeListener;

public class TouchView extends View{


    private File tempFile;
    private byte[] imageArray;
    private Bitmap bgr;

    private Bitmap crop;
    private Bitmap crop2;
    private Bitmap overLay;
    private Bitmap overLay2;


    private float centreX;
    private float centreY;
    private float centreA = 200;
    private float centreB = 200;
    private Boolean xyFound = false;
    private int Progress = 1;
    private static final String TAG = "*********TouchView";
    private Filters f = null;
    private boolean bothCirclesInPlace = false;
    private MultiProcessorFilter mpf;
    private MultiProcessorFilter mpf2;
    private MultiRuntimeProcessorFilter mrpf;
    private MultiRuntimeProcessorFilter mrpf2;





    public TouchView(Context context) {
        super(context);

    }




    public TouchView(Context context, AttributeSet attr) {
        super(context,attr);
        Log.e(TAG, "++++++++++ inside touchview constructor");



        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();
            }


       Bitmap bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length);




        bgr = bm.copy(bm.getConfig(), true);;

        overLay = null;
        overLay2 = null;



       bm.recycle();

    }// end of touchView constructor




    public void findCirclePixels(){ 

         //  f = new Filters();
         //  mpf = new MultiProcessorFilter();
         //  mpf2 = new MultiProcessorFilter();
         mrpf = new MultiRuntimeProcessorFilter();
         mrpf2 = new MultiRuntimeProcessorFilter();

         crop = Bitmap.createBitmap(bgr,Math.max((int)centreX-75,0),Math.max((int)centreY-75,0),150,150);
         crop2 = Bitmap.createBitmap(bgr,Math.max((int)centreA-75,0),Math.max((int)centreB-75,0),150,150);

              new Thread(new Runnable() {
                public void run() {
                    float prog = (float)Progress/150001;

               // final Bitmap bgr3 = f.barrel(crop,prog);
               // final Bitmap bgr4 = f.barrel(crop2,prog);

              //  final Bitmap bgr3 = mpf.barrel(crop,prog);
              //  final Bitmap bgr4 = mpf2.barrel(crop2,prog);

                    final Bitmap bgr3 = mrpf.barrel(crop,prog);
                    final Bitmap bgr4 = mrpf2.barrel(crop2,prog);

                  TouchView.this.post(new Runnable() {
                    public void run() {


                      TouchView.this.overLay = bgr3;
                      TouchView.this.overLay2 = bgr4;

                      TouchView.this.invalidate();

                    }
                  });
                }
              }).start();


        }// end of changePixel()






    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

            case MotionEvent.ACTION_DOWN: {

                if(xyFound == false){
                centreX = (int) ev.getX();
                centreY = (int) ev.getY();
                xyFound = true;
                }else{
                centreA = (int) ev.getX();
                centreB = (int) ev.getY();
                bothCirclesInPlace  = true;
                }


                break;
            }

          /*  case MotionEvent.ACTION_MOVE: {

                if(xyFound == false){
                    centreX = (int) ev.getX();
                    centreY = (int) ev.getY();
                    xyFound = true;
                }else{
                    centreA = (int) ev.getX();
                    centreB = (int) ev.getY();
                    bothCirclesInPlace = true;
                    }

                    findCirclePixels();
                 // TouchView.this.invalidate();
                    break;

            }*/           

            case MotionEvent.ACTION_UP: 

                break;

        }
        return true;
    }//end of onTouchEvent





    public void initSlider(final HorizontalSlider slider)
    {

        slider.setOnProgressChangeListener(changeListener);


    }



    private OnProgressChangeListener changeListener = new OnProgressChangeListener() {


        @Override
        public void onProgressChanged(View v, int progress) {



              setProgress(progress);



        }
    };




    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);

        Log.e(TAG, "******about to draw bgr ");
        canvas.drawBitmap(bgr, 0, 0, null);

        if(bothCirclesInPlace == true){

                if(overLay != null){
                    Log.e(TAG, "******about to draw overlay1 ");
        canvas.drawBitmap(overLay, centreX-75, centreY-75, null);
                }
            if(overLay2 != null){
                Log.e(TAG, "******about to draw overlay2 ");
        canvas.drawBitmap(overLay2, centreA-75, centreB-75, null);
            }

        }

    }//end of onDraw




    protected void setProgress(int progress2) {
        Log.e(TAG, "***********in SETPROGRESS");
        this.Progress = progress2;



        findCirclePixels();


    }




}
Run Code Online (Sandbox Code Playgroud)

.

呼叫活动.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Jjilapp extends Activity {




    private static final String TAG = "*********jjil";


    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.touchview);
        final TouchView touchView = (TouchView)findViewById(R.id.touchview); 
        final HorizontalSlider slider = (HorizontalSlider)findViewById(R.id.slider); 

        touchView.initSlider(slider);




    }//end of oncreate




}
Run Code Online (Sandbox Code Playgroud)

如果你需要任何帮助伙伴,请问.希望这可以帮助