• 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

  • 相关阅读:
    多屏显示
    Scss sass
    静态页面常用到
    display:flex
    怎么看服务器是属于阿里云的还是腾讯云
    介绍一款好用 mongodb 可视化工具
    图解Mongo Shell的使用
    Win10 安装配置 MongoDB 4.0 踩坑记
    phpexcel来做表格导出(多个工作sheet)及设置单元格格式
    phpexcel 导出方法
  • 原文地址:https://www.cnblogs.com/mgstone/p/5852043.html
Copyright © 2020-2023  润新知