行走的Coder

俱怀逸兴壮思飞,欲上青天览明月。

导航

JAVA层和JNI层实现Bitmap图镜像功能。

写在前面:

经过几天查阅资料,终于完成镜像功能,其中加载位图时需对位图进行处理,主要原因是因为超过8M的位图加载进进程会出现内存溢出,图片处理包含两个部分:缩放处理和质量处理。

我这里选择的是质量处理。Java层代码很简单,网上资料很多,JNI层使用C++实现,传三个参数,即存像素的Int数组,图片宽和图片高,其实这里传进来二维数组会更好处理。

JAVA代码:

public class MainActivity extends Activity {  
        /** Called when the activity is first created. */  
        Button  btnJAVA,btnJNI;  
        Button btn;
        ImageView imgView;  
        int quality=1000;
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  

            btn=(Button)this.findViewById(R.id.btn);  
            btn.setOnClickListener(new ClickEvent());  
            
            btnJAVA=(Button)this.findViewById(R.id.btnJAVA);  
            btnJAVA.setOnClickListener(new ClickEvent());  
              
            btnJNI=(Button)this.findViewById(R.id.btnJNI);  
            btnJNI.setOnClickListener(new ClickEvent());  
            imgView=(ImageView)this.findViewById(R.id.ImageView01);  
        }  
        class ClickEvent implements View.OnClickListener{  
            @Override  
            public void onClick(View v) {  
                if(v==btnJAVA)  
                {  
                    Bitmap mBitmap;
                    try {
                        mBitmap = revitionImageSize("bg.jpg", quality);
                        Bitmap mmBitmap=convertBmp(mBitmap);
                        imgView.setImageBitmap(mmBitmap);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }  
                else if(v==btnJNI)  
                {  
                    //先打开图像并读取像素  
                    Bitmap img1;
                    try {
                        img1 = revitionImageSize("bg.jpg", quality);
                        int w=img1.getWidth(),h=img1.getHeight();  
                        int[] pix = new int[w * h];  
                        img1.getPixels(pix, 0, w, 0, 0, w, h);  
                        int[] resultInt=Convert.Convert(pix, w, h);  
                        Bitmap resultImg=Bitmap.createBitmap(w, h, Config.RGB_565);  
                        resultImg.setPixels(resultInt, 0, w, 0, 0,w, h);  
                        imgView.setImageBitmap(resultImg);  
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }  
                else if(v==btn)  
                {  
                    Bitmap mBitmap;
                    try {
                        mBitmap = revitionImageSize("bg.jpg", quality);
                        imgView.setImageBitmap(mBitmap);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }  
            }  
        }  
        /*缩小位图处理*/
        private Bitmap revitionImageSize(String path, int size) throws IOException {
            InputStream temp = this.getAssets().open(path);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(temp, null, options);
            temp.close();

            int i = 0;
            Bitmap bitmap = null;
            while (true) {
                if ((options.outWidth >> i <= size)
                        && (options.outHeight >> i <= size)) {
                    temp = this.getAssets().open(path);
                    options.inSampleSize = (int) Math.pow(2.0D, i);
                    options.inJustDecodeBounds = false;
                    bitmap = BitmapFactory.decodeStream(temp, null, options);
                    break;
                }
                i += 1;
            }
            return bitmap;
        }
                
        /*Java层实现镜像功能*/
        public Bitmap convertBmp(Bitmap bmp){
            int w = bmp.getWidth();
            int h = bmp.getHeight();
         
            Bitmap convertBmp = Bitmap.createBitmap(w, h, Config.ARGB_8888);  
            Canvas cv = new Canvas(convertBmp);
            Matrix matrix = new Matrix();
            matrix.postScale(-1, 1);
            Bitmap newBmp = Bitmap.createBitmap(bmp, 0, 0, w, h, matrix, true);
            cv.drawBitmap(newBmp, new Rect(0, 0,newBmp.getWidth(), newBmp.getHeight()),new Rect(0, 0, w, h), null);
            return convertBmp;
            }
    } 

JNI层C++代码:

    #include <jni.h>
    #include <stdio.h>
    #include <stdlib.h>
   using namespace std;
    extern "C" {
    JNIEXPORT jintArray JNICALL Java_com_example_convertbitmap_Convert_Convert(
            JNIEnv* env, jobject obj, jintArray buf, int w, int h);
    }
    ;
    JNIEXPORT jintArray JNICALL Java_com_example_convertbitmap_Convert_Convert(
            JNIEnv* env, jobject obj, jintArray buf, int w, int h) {
        jint *cbuf;
        cbuf = env->GetIntArrayElements(buf, false);
        if (cbuf == NULL) {
            return 0; /* exception occurred */
        }
        int alpha = 0xFF << 24;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w/2; j++) {
               //像素交换
                int tmp=cbuf[i*w+j];
                cbuf[i*w+j]=cbuf[(i+1)*w-j-1];
                cbuf[(i+1)*w-j-1]=tmp;
            }
        }

        int size=w * h;
        jintArray result = env->NewIntArray(size);
        env->SetIntArrayRegion(result, 0, size, cbuf);
        env->ReleaseIntArrayElements(buf, cbuf, 0);
        return result;
    }

github代码链接:https://github.com/mgstone/mygit/tree/master/ConvertBitmap

posted on 2016-09-08 10:22  行走的coder  阅读(717)  评论(0编辑  收藏  举报