精华内容
下载资源
问答
  • android二维码扫描本地图片

    千次阅读 2015-11-16 16:34:53
    关于android zxing二维码开发这方面的技术,现在大家比较常用到的扫描二维码扫描本地图片,今天刚解决的一个问题就是我的扫描本地图片二维码的功能老存在问题,有的二维码可以扫出来,有的扫不出来,看网上的帖子...

    关于android zxing二维码开发这方面的技术,现在大家比较常用到的扫描二维码和扫描本地图片,今天刚解决的一个问题就是我的扫描本地图片二维码的功能老存在问题,有的二维码可以扫出来,有的扫不出来,看网上的帖子有人说需要什么将rgb转换成黑白,还有的说要转成yuv格式,试了一下,没有解决自己的问题,有可能我的技术还不到位吧,最后在一个demo里找到了这种方法,直接就解决了问题。

    private void decode(final String picturePath) {
    			
    			new Thread() {
    				@Override
    				public void run() {
    					
    					
    					Bitmap image = BitmapFactory.decodeFile(picturePath);
    					Bitmap bitmap = reduce(image,50,50,true);
    					RGBLuminanceSource source = new RGBLuminanceSource(bitmap);
    					BinaryBitmap binaryBitmap = new BinaryBitmap(
    							new HybridBinarizer(source));
    					Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
    					hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
    					QRCodeReader reader = new QRCodeReader();
    					Result result = null;
    					try {
    						result = reader.decode(binaryBitmap, hints);
    					} catch (NotFoundException e) {
    						e.printStackTrace();
    					} catch (ChecksumException e) {
    						e.printStackTrace();
    					} catch (FormatException e) {
    						e.printStackTrace();
    					} finally {
    						reader.reset();
    					}
    					Message message = Message.obtain();
    					if (result != null) {
    						message.what = 0;
    						message.obj = result.getText();
    					} else {
    						message.what = 1;
    					}
    					scanHandler.sendMessage(message);
    				}
    			}.start();
    
    		}
    
    		private Handler scanHandler = new Handler() {
    
    			@Override
    			public void handleMessage(Message msg) {
    				
    				if (msg.what == 0) {
    					
    					//扫描成功获取信息
    					Intent intent = new Intent(Details.this,WebViewactivity.class);
    					   intent.putExtra("txt", msg.obj.toString());
    					   startActivity(intent);
    				} else {
    					Toast.makeText(Details.this, "失败", Toast.LENGTH_LONG)
    							.show();
    				}
    
    				super.handleMessage(msg);
    			}
    
    		};


    /**
    		 * 压缩图片
    		 * @param bitmap 源图片
    		 * @param width 想要的宽度
    		 * @param height 想要的高度
    		 * @param isAdjust 是否自动调整尺寸, true图片就不会拉伸,false严格按照你的尺寸压缩
    		 * @return Bitmap
    		 * @author wangyongzheng
    		 */
    		public Bitmap reduce(Bitmap bitmap, int width, int height, boolean isAdjust) {
    			// 如果想要的宽度和高度都比源图片小,就不压缩了,直接返回原图
    			if (bitmap.getWidth() < width && bitmap.getHeight() < height) {return bitmap;}
    			// 根据想要的尺寸精确计算压缩比例, 方法详解:public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode);
    			// scale表示要保留的小数位, roundingMode表示如何处理多余的小数位,BigDecimal.ROUND_DOWN表示自动舍弃
    			float sx = new BigDecimal(width).divide(new BigDecimal(bitmap.getWidth()), 4, BigDecimal.ROUND_DOWN).floatValue();
    			float sy = new BigDecimal(height).divide(new BigDecimal(bitmap.getHeight()), 4, BigDecimal.ROUND_DOWN).floatValue();
    			if (isAdjust) {// 如果想自动调整比例,不至于图片会拉伸
    				sx = (sx < sy ? sx : sy);sy = sx;// 哪个比例小一点,就用哪个比例
    			}
    			Matrix matrix = new Matrix();
    			matrix.postScale(sx, sy);// 调用api中的方法进行压缩,就大功告成了
    			return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    		}



    展开全文
  • 我们在开发时候经常会用到二维码扫描,今天我们来实现下 1.首先导入一个一片枫叶的依赖 compile 'cn.yipianfengye.android:zxing-library:2.2 添加权限 &lt;uses-permission android:name="android....

    我们在开发时候经常会用到二维码扫描,今天我们来实现下

    1.首先导入一个一片枫叶的依赖

    compile 'cn.yipianfengye.android:zxing-library:2.2

    添加权限

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    2.直接上代码,自带二维码Activty部分

    public class MainActivity extends AppCompatActivity {
        //设置标记
        private static final int REQUEST_CODE = 0;
        private static final int REQUEST_IMAGE = 1;
        private EditText text;
        private ImageView imageView;
        private Bitmap bitmap;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button but1 = (Button) findViewById(R.id.button1);
            /**
             * 打开默认二维码扫描界面
             */
            but1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    //CaptureActivity是一个封装好的Activity
                    Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                    startActivityForResult(intent,REQUEST_CODE);
                }
            });
    
            //从相册打开二维码进行识别
            Button but2 = (Button) findViewById(R.id.button2);
            but2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //打开相册
                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("image/*");
                    startActivityForResult(intent, REQUEST_IMAGE);
                }
            });
    
            text = (EditText) findViewById(R.id.edit);
            imageView = (ImageView) findViewById(R.id.image);
            Button make1 = (Button) findViewById(R.id.make_button1);
            //生成带有图片的二维码
            make1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String textContent = text.getText().toString();
                    if (TextUtils.isEmpty(textContent)) {
                        Toast.makeText(MainActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    text.setText("");
                    //设置图片大小
                    bitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
                    imageView.setImageBitmap(bitmap);
                }
            });
    
            Button make2 = (Button) findViewById(R.id.make_button2);
            //生成不带图片的二维码
            make2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String textContent = text.getText().toString();
                    makeImage(textContent);
                }
            });
    
        }
    
        //生成带有图片二维码
        private void makeImage(String textContent) {
            if (TextUtils.isEmpty(textContent)) {
                Toast.makeText(MainActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                return;
            }
            text.setText("");
            bitmap = CodeUtils.createImage(textContent, 400, 400, null);
            imageView.setImageBitmap(bitmap);
        }
    
        //回调
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            Log.i("tag","================"+requestCode);
            if(requestCode == REQUEST_CODE) {
                //处理扫描结果(在界面上显示)
                if (null != data) {
                    Bundle bundle = data.getExtras();
                    if (bundle == null) {
                        return;
                    }
                    if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                        String result = bundle.getString(CodeUtils.RESULT_STRING);
                        Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                        makeImage(result);
                    } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                        Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                    }
                }
            }
    
            //图片
            if (requestCode == REQUEST_IMAGE) {
                if (data != null) {
                    Uri uri = data.getData();
                    ContentResolver cr = getContentResolver();
                    try {
                        Bitmap mBitmap = MediaStore.Images.Media.getBitmap(cr, uri);//显得到bitmap图片
    
                        CodeUtils.analyzeBitmap(String.valueOf(mBitmap), new CodeUtils.AnalyzeCallback() {
                            @Override
                            public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
                                Toast.makeText(MainActivity.this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                            }
    
                            @Override
                            public void onAnalyzeFailed() {
                                Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                            }
                        });
    
                        if (mBitmap != null) {
                            mBitmap.recycle();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    xml部分

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.mdj.acer.zxing.MainActivity">
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="简单扫描"
            />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选择图片并解析"
            />
    
        <EditText
            android:id="@+id/edit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />
    
        <Button
            android:id="@+id/make_button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="生成Logo二维码图片"
            />
    
    
        <Button
            android:id="@+id/make_button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="生成普通二维码图片"
            />
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    

     

    3.自定义的二维码扫描

    首先是主要的Activity,由于只写了一个Button,就不上视图了

    private static final int REQUEST_CODE = 0;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ZXingLibrary.initDisplayOpinion(this);
        Button but = (Button) findViewById(R.id.button);
        but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivityForResult(intent, REQUEST_CODE);
            }
        });
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.i("tag","==========="+requestCode);
        /**
         * 处理二维码扫描结果
         */
        if (requestCode == REQUEST_CODE) {
            //处理扫描结果(在界面上显示)
            if (null != data) {
                Bundle bundle = data.getExtras();
                if (bundle == null) {
                    return;
                }
                if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                    String result = bundle.getString(CodeUtils.RESULT_STRING);
                    Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                    Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    负责处理扫描逻辑的Activity

    public class Main2Activity extends AppCompatActivity {
        private boolean bool = true;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
            /**
             * 执行扫面Fragment的初始化操作
             */
            CaptureFragment captureFragment = new CaptureFragment();
            // 为二维码扫描界面设置定制化界面
            CodeUtils.setFragmentArgs(captureFragment, R.layout.my_camera);
            captureFragment.setAnalyzeCallback(analyzeCallback);
            /**
             * 替换我们的扫描控件
             */
            getSupportFragmentManager().beginTransaction().replace(R.id.fl_my_container, captureFragment).commit();
    
            ImageView image = (ImageView) findViewById(R.id.image);
            image.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(bool){
                        /**
                         * 打开闪光灯
                         */
                        CodeUtils.isLightEnable(true);
                        bool = false;
                    }else{
                        /**
                         * 关闭闪光灯
                         */
                        CodeUtils.isLightEnable(false);
                        bool = true;
                    }
                }
            });
        }
    
        /**
         * 二维码解析回调函数
         */
        CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {
            @Override
            public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
                Intent resultIntent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
                bundle.putString(CodeUtils.RESULT_STRING, result);
                resultIntent.putExtras(bundle);
                Main2Activity.this.setResult(RESULT_OK, resultIntent);
                Main2Activity.this.finish();
            }
    
            @Override
            public void onAnalyzeFailed() {
                Intent resultIntent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
                bundle.putString(CodeUtils.RESULT_STRING, "");
                resultIntent.putExtras(bundle);
                Main2Activity.this.setResult(RESULT_OK, resultIntent);
                Main2Activity.this.finish();
            }
        };
    }

    处理逻辑ActivityXml视图

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.mdj.acer.make.Main2Activity">
    
        <FrameLayout
            android:id="@+id/layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
    
            <FrameLayout
                android:id="@+id/fl_my_container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                ></FrameLayout>
    
        </FrameLayout>
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:id="@+id/image"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="20dp"
            />
    
    </RelativeLayout>
    

     

    扫描框布局

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!--标题栏-->
        <RelativeLayout
            android:id="@+id/biaoti"
            android:layout_width="match_parent"
            android:layout_height="48dp">
            <TextView
                android:id="@+id/text_title"
                android:text="标题栏"
                android:textSize="17sp"
                android:textColor="#fff"
                android:singleLine="true"
                android:ellipsize="marquee"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
            <ImageView
                android:padding="6dp"
                android:src="@mipmap/ic_launcher"
                android:id="@+id/button_backward"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:gravity="center"
                android:paddingLeft="5dp"
                />
        </RelativeLayout>
    
        <FrameLayout
            android:id="@+id/frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/biaoti"
            >
    
            <SurfaceView
                android:id="@+id/preview_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            
            <!--app:inner_corner_color="#0f0" 边框颜色-->
            <!--app:inner_scan_bitmap="@mipmap/ic_launcher" 扫描线图片-->
            <com.uuzuche.lib_zxing.view.ViewfinderView
                android:id="@+id/viewfinder_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:inner_width="200dp"
                app:inner_height="200dp"
                app:inner_margintop="150dp"
                app:inner_corner_color="#0f0"
                app:inner_corner_length="30dp"
                app:inner_corner_width="5dp"
                app:inner_scan_bitmap="@mipmap/ic_launcher"
                app:inner_scan_speed="15"
                app:inner_scan_iscircle="false"
                />
        </FrameLayout>
    
    </RelativeLayout>

     

    这样二维码扫描功能就完成了,自定义的有点low,不过功能实现了,简单修改布局就好了....

    展开全文
  • 二维码扫描

    千次阅读 2016-06-20 15:21:45
    二维码扫描,AVFoundation,ZBar,
       本文中我们介绍一下如何在iOS平台实现二维码扫描,我们可以借助一些优秀的第三方库,比如ZBar SDK和ZXing。在iOS7.0之后,我们也可以使用iOS系统原生扫描,通过AVFoundation框架来实现二维码扫描,不过AVFoundation框架不能识别相册中的二维码图片。
    

    1. 通过AVFoundation框架识别二维码

    1.1 AVFoundation框架扫描二维码的基本方法

    我们先来介绍一下如何使用AVFoundation框架实现二维码扫描。在iOS7之后,苹果自身提供了二维码的扫描功能,从效率上来说,原生的二维码远高于这些第三方框架。之前我们使用AVFoundation框架实现过拍照功能,基本的原理差不多类似;需要AVCaptureSession对象管理输入流和输出流;需要一个AVCaptureVideoPreviewLayer对象来显示信息。基本流程如下:
    这里写图片描述

    图中涉及到的几个相关类的说明如下:

    • AVCaptureSession 管理输入(AVCaptureInput)和输出(AVCaptureOutput)流,包含开启和停止会话方法。
    • AVCaptureDeviceInput 是AVCaptureInput的子类,可以作为输入捕获会话,用AVCaptureDevice实例初始化。
    • AVCaptureDevice 代表了物理捕获设备如:摄像机。用于配置等底层硬件设置相机的自动对焦模式。
    • AVCaptureMetadataOutput 是AVCaptureOutput的子类,处理输出捕获会话。捕获的对象传递给一个委托实现AVCaptureMetadataOutputObjectsDelegate协议。协议方法在指定的派发队列(dispatch queue)上执行。
    • AVCaptureVideoPreviewLayerCALayer的一个子类,显示捕获到的相机输出流。

    下面我们看一下具体的实现步骤:
    示例代码:

    #import "ViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
    
    @property (weak, nonatomic) IBOutlet UISwitch *lightSwitch;// 闪光开关
    @property (nonatomic) AVCaptureSession *captureSession;//捕获的管理会话
    @property (nonatomic) AVCaptureVideoPreviewLayer *previewLayer;// 预览图层
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    // 开始二维码扫描
    - (IBAction)startScan:(UIButton *)sender {
    
        // 1. 初始化捕获会话,并添加输入对象
        self.captureSession = [[AVCaptureSession alloc] init];
    
        // 2. 初始化捕获设备对象AVCaptureDevice
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
        // 3. 初始化捕获设备的输入对象AVCaptureDeviceInput
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        if (input == nil) {
            NSLog(@"输入对象初始化失败");
            return;
        }
    
        // 将输入对象添加到会话
        [self.captureSession addInput:input];
    
        // 4. 初始化输出对象AVCaptureMetadataOutput
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    
        // 将输出对象添加到会话
        [self.captureSession addOutput:output];
        // 设置输出对象源数据类型:AVMetadataObjectTypeQRCode条码类型
        [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
        // 设置输出对象代理,并实现代理方法
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
        // 设置扫码区域为预览区域 默认全屏扫描
        CGFloat w = self.view.frame.size.width;
        CGFloat h = self.view.frame.size.height;
        // rectOfInterest属性:区域大小是相对于设备的大小的,默认值是(0, 0, 1, 1)。但是区域的坐标系统X和Y是互换的,同时,宽高的比例也互换了。
        [output setRectOfInterest:CGRectMake((h/2 -100)/h, (w/2 -100)/w, 200/h, 200/w)];
        NSLog(@"%@",NSStringFromCGRect(output.rectOfInterest));
    
        // 5. 初始化预览图层
        self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
        self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;// 拉伸属性
        self.previewLayer.frame = self.view.bounds;
        [self.view.layer addSublayer:self.previewLayer];
    
        // 6.开始会话
        [self.captureSession startRunning];
    
        // 关闭闪光灯
        self.lightSwitch.on = NO;
        [self.view bringSubviewToFront:self.lightSwitch];
    }
    
    #pragma mark -
    #pragma mark - AVCaptureMetadataOutputObjectsDelegate
    // 此方法是在识别到QRCode,并且完成转换。如果QRCode的内容越大,转换需要的时间就越长
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    
        if (metadataObjects != nil && [metadataObjects count] > 0) {
    
            // 扫码成功 停止扫描,
            [self.captureSession stopRunning];
    
            // 获取扫码结果:
            AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
            NSString *result;
            if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
                result = metadataObj.stringValue;
                NSLog(@"%@",result);
            } else {
                NSLog(@"不是二维码");
            }
        }
    }
    
    #pragma mark -
    #pragma mark - 开启闪光灯
    - (IBAction)lightOpenOrClose:(UISwitch *)sender {
    
        BOOL isOpen = sender.on;
        // 获取设备
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch]) {
            [device lockForConfiguration:nil];
            if (isOpen) {
                [device setTorchMode:AVCaptureTorchModeOn];
            } else {
                [device setTorchMode:AVCaptureTorchModeOff];
            }
            [device unlockForConfiguration];
        }
    }
    
    @end

    1.2 AVFoundation框架扫描二维码的功能封装
    上面是系统自带的二维码扫描的基本功能实现,下面我们来实现一下在实际开发中二维码扫描的实际效果,不过就是添加了一条扫描的线条。
    示例代码:
    Scan2CodeViewController.h

    #import <UIKit/UIKit.h>
    
    @protocol ScanImageViewDelegate<NSObject>
    
    - (void)reportScanResult:(NSString *)result;
    
    @end
    
    @interface Scan2CodeViewController : UIViewController
    
    @property (nonatomic,weak)id <ScanImageViewDelegate>delegate;//代理方法传递数据
    
    @end
    示例代码:
    Scan2CodeViewController.m
    #import "Scan2CodeViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    #define SCANVIEW_EdgeTop 70.0
    #define SCANVIEW_EdgeLeft 50.0
    #define TINTCOLOR_ALPHA 0.2 //浅色透明度
    #define DARKCOLOR_ALPHA 0.3 //深色透明度
    #define VIEW_WIDTH [UIScreen mainScreen].bounds.size.width
    #define VIEW_HEIGHT [UIScreen mainScreen].bounds.size.height
    
    static const char *kScanQRCodeQueueName = "ScanQRCodeQueue";
    @interface Scan2CodeViewController () <AVCaptureMetadataOutputObjectsDelegate>{
        //设置扫描画面
        UIView *_scanView;
        NSTimer *_timer;
    
        UIView *_QrCodeline;
        UIView *_QrCodeline1;
        UIImageView *_scanCropView;//扫描窗口
        UIButton *_lightButton;//灯光按钮
        AVCaptureSession *_captureSession;
        AVCaptureVideoPreviewLayer *_videoPreviewLayer;
    }
    
    @end
    
    @implementation Scan2CodeViewController
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    
        [self stopTimer];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //初始化扫描界面
        [self setScanView];
    
        // 开始扫描
        [self startReading];
    
        //启动定时器
        [self createTimer];
    }
    
    - (BOOL)startReading
    {
        // 获取 AVCaptureDevice 实例
        NSError * error;
        AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        // 初始化输入流
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
        if (!input) {
            NSLog(@"%@", [error localizedDescription]);
            return NO;
        }
        // 创建会话
        _captureSession = [[AVCaptureSession alloc] init];
        //提高图片质量为1080P,提高识别效果
        _captureSession.sessionPreset = AVCaptureSessionPreset1920x1080;
        // 添加输入流
        [_captureSession addInput:input];
        // 初始化输出流
        AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
    
        //设置扫描范围
        captureMetadataOutput.rectOfInterest =CGRectMake((_scanCropView.frame.origin.y-10)/VIEW_HEIGHT, (_scanCropView.frame.origin.x-10)/VIEW_WIDTH, (_scanCropView.frame.size.width+10)/VIEW_HEIGHT, (_scanCropView.frame.size.height+10)/VIEW_WIDTH);
    
        // 添加输出流
        [_captureSession addOutput:captureMetadataOutput];
    
        // 创建dispatch queue.
        dispatch_queue_t dispatchQueue;
        dispatchQueue = dispatch_queue_create(kScanQRCodeQueueName, NULL);
        [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
        // 设置元数据类型 AVMetadataObjectTypeQRCode
        [captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
    
        // 创建输出对象
        _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
        [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    
        [_videoPreviewLayer setFrame:_scanView.layer.bounds];
        [_scanView.layer insertSublayer:_videoPreviewLayer atIndex:0];
        // 开始会话
        [_captureSession startRunning];
    
        return YES;
    }
    
    - (void)stopReading
    {
        // 停止会话
        [_captureSession stopRunning];
        _captureSession = nil;
    }
    
    #pragma mark -
    #pragma mark - AVCaptureMetadataOutputObjectsDelegate
    -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
          fromConnection:(AVCaptureConnection *)connection
    {
        if (metadataObjects != nil && [metadataObjects count] > 0) {
            AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
            NSString *result;
            if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
                result = metadataObj.stringValue;
            } else {
                NSLog(@"不是二维码");
            }
            //调用代理对象的协议方法来实现数据传递
            [self dismissViewControllerAnimated:YES completion:nil];
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(reportScanResult:)]) {
                    [self.delegate reportScanResult:result];
                }
            });
            [self stopReading];
        }
        return;
    }
    - (void)createTimer
    {
        _timer=[NSTimer scheduledTimerWithTimeInterval:2.2 target:self selector:@selector(moveUpAndDownLine) userInfo:nil repeats:YES];
    }
    - (void)stopTimer
    {
        if ([_timer isValid] == YES) {
            [_timer invalidate];
            _timer = nil;
        }
    
    }
    
    // 二维码的扫描区域
    - (void)setScanView
    {
        _scanView=[[UIView alloc] initWithFrame:CGRectMake(0,0, VIEW_WIDTH,VIEW_HEIGHT )];
        _scanView.backgroundColor=[UIColor clearColor];
        [self.view addSubview:_scanView];
    
        //最上部view
        UIView *upView = [[UIView alloc] initWithFrame:CGRectMake(0,0, VIEW_WIDTH,SCANVIEW_EdgeTop)];
        upView.alpha =TINTCOLOR_ALPHA;
        upView.backgroundColor = [UIColor blackColor];
        [_scanView addSubview:upView];
    
        //左侧的view
        UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, SCANVIEW_EdgeTop, SCANVIEW_EdgeLeft,VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft)];
        leftView.alpha =TINTCOLOR_ALPHA;
        leftView.backgroundColor = [UIColor blackColor];
        [_scanView addSubview:leftView];
    
        // 中间扫描区
        _scanCropView=[[UIImageView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft,SCANVIEW_EdgeTop, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft)];
        //scanCropView.image=[UIImage imageNamed:@""];
        _scanCropView.layer.borderColor=[UIColor greenColor].CGColor;
        _scanCropView.layer.borderWidth=2.0;
        _scanCropView.backgroundColor=[UIColor clearColor];
        [_scanView addSubview:_scanCropView];
    
        //右侧的view
        UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(VIEW_WIDTH - SCANVIEW_EdgeLeft,SCANVIEW_EdgeTop, SCANVIEW_EdgeLeft, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft)];
        rightView.alpha =TINTCOLOR_ALPHA;
        rightView.backgroundColor = [UIColor blackColor];
        [_scanView addSubview:rightView];
    
        //底部view
        UIView *downView = [[UIView alloc] initWithFrame:CGRectMake(0, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop, VIEW_WIDTH, VIEW_HEIGHT - (VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop))];
        //downView.alpha = TINTCOLOR_ALPHA;
        downView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:TINTCOLOR_ALPHA];
        [_scanView addSubview:downView];
    
        //用于说明的label
        UILabel *labIntroudction= [[UILabel alloc] init];
        labIntroudction.backgroundColor = [UIColor clearColor];
        labIntroudction.frame=CGRectMake(0,5, VIEW_WIDTH,20);
        labIntroudction.numberOfLines=1;
        labIntroudction.font=[UIFont systemFontOfSize:15.0];
        labIntroudction.textAlignment=NSTextAlignmentCenter;
        labIntroudction.textColor=[UIColor whiteColor];
        labIntroudction.text=@"将二维码对准方框,即可自动扫描";
        [downView addSubview:labIntroudction];
    
        //取消button
        UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        cancelButton.backgroundColor =[[UIColor blackColor] colorWithAlphaComponent:DARKCOLOR_ALPHA];
        cancelButton.frame =CGRectMake(0, 90, VIEW_WIDTH, 40);
        cancelButton.titleLabel.font =[UIFont systemFontOfSize:15.0];
        cancelButton.titleLabel.textAlignment = NSTextAlignmentCenter;
        [cancelButton setTitle:@"取消" forState:UIControlStateNormal];
        [cancelButton addTarget:self action:@selector(cancelAction) forControlEvents:UIControlEventTouchUpInside];
        [downView addSubview:cancelButton];
    
        //用于开关灯操作的button
        _lightButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _lightButton.frame =CGRectMake(0, 40, VIEW_WIDTH, 40);
        [_lightButton setTitle:@"开启闪光灯" forState:UIControlStateNormal];
        [_lightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _lightButton.backgroundColor =[[UIColor blackColor] colorWithAlphaComponent:DARKCOLOR_ALPHA];
        _lightButton.titleLabel.textAlignment=NSTextAlignmentCenter;
        _lightButton.titleLabel.font=[UIFont systemFontOfSize:15.0];
        [_lightButton addTarget:self action:@selector(openLight) forControlEvents:UIControlEventTouchUpInside];
        [downView addSubview:_lightButton];
    
        //画中间的基准线
        _QrCodeline = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop, VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft, 2)];
        _QrCodeline.backgroundColor = [UIColor greenColor];
        [_scanView addSubview:_QrCodeline];
    
        //画中间的基准线
        _QrCodeline1 = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop, VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft, 2)];
        _QrCodeline1.backgroundColor = [UIColor greenColor];
        [_scanView addSubview:_QrCodeline1];
    
        // 先让第二根线运动一次,避免定时器执行的时差,让用户感到启动App后,横线就开始移动
        [UIView animateWithDuration:2.2 animations:^{
    
            _QrCodeline1.frame = CGRectMake(SCANVIEW_EdgeLeft, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop - 2, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft, 1);
        }];
    
    
    }
    
    // 当地一根线到达底部时,第二根线开始下落运动,此时第一根线已经在顶部,当第一根线接着下落时,第二根线到达顶部.依次循环
    - (void)moveUpAndDownLine
    {
        CGFloat Y = _QrCodeline.frame.origin.y;
        if (Y == SCANVIEW_EdgeTop) {
            [UIView animateWithDuration:2.2 animations:^{
    
                _QrCodeline.frame = CGRectMake(SCANVIEW_EdgeLeft, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop - 2, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft, 1);
            }];
            _QrCodeline1.frame = CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft, 1);
        }
        else if (Y == VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop - 2) {
            _QrCodeline.frame = CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft, 1);
            [UIView animateWithDuration:2.2 animations:^{
    
                _QrCodeline1.frame = CGRectMake(SCANVIEW_EdgeLeft, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop - 2, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft, 1);
            }];
        }
    
    }
    
    //照明灯光
    -(void)openLight{
        if ([_lightButton.titleLabel.text isEqualToString:@"开启闪光灯"]) {
            [self systemLightSwitch:YES];
        } else {
            [self systemLightSwitch:NO];
        }
    }
    
    - (void)systemLightSwitch:(BOOL)open
    {
        if (open) {
            [_lightButton setTitle:@"关闭闪光灯" forState:UIControlStateNormal];
        } else {
            [_lightButton setTitle:@"开启闪光灯" forState:UIControlStateNormal];
        }
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch]) {
            [device lockForConfiguration:nil];
            if (open) {
                [device setTorchMode:AVCaptureTorchModeOn];
            } else {
                [device setTorchMode:AVCaptureTorchModeOff];
            }
            [device unlockForConfiguration];
        }
    }
    
    // 取消button
    - (void)cancelAction{
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    @end

    2. 使用ZBarSDK识别二维码

       在iOS7.0以前,大部分应用识别二维码都是通过第三方库来实现的。事实上,在主流APP中二维码/条形码的作用主要分三种表现形式来集成:
    
    • 调用手机摄像头并打开系统照相机全屏去拍摄。
    • 自定义照相机视图的frame,自己控制并添加相关扫码指南。
    • 识别相册图片中的二维码图片。

      首先我们先来看一下如何集成ZBarSDK:
      第一步:将 ZBarSDK导入到工程,并集成相关的框架,

    • AVFoundation.framework
    • CoreMedia.framework
    • CoreVideo.framework
    • QuartzCore.framework
    • libiconv.dylib
      如下图:
      这里写图片描述
      第二步:关闭代码优化
      导入相关框架后,系统编译仍然不通过,提示的错误如下:
      这里写图片描述
      这是由于系统代码优化产生的错误,将Xcode的bitcode选项设置为No就可以通过编译了。
      这里写图片描述

      第三步:导入头文件,初始化ZBar相机控制器,并实现相关代理;

    • 调用系统相机全屏拍摄,使用ZBarReaderViewController,并声明协议。
    • 自定义扫描窗口,使用ZBarReaderView,并声明协议。
    • 识别相册的二维码图片,使用ZBarReaderController,并声明

    2.1 调用系统相机:

    示例代码:

    #import "ViewController.h"
    #import "ZBarSDK.h"
    
    @interface ViewController ()<ZBarReaderDelegate>
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    - (IBAction)systemCamara:(id)sender {
    
        // 初始化扫码视图控制器
        ZBarReaderViewController *reader = [ZBarReaderViewController new];
    
        // 设置代理
        reader.readerDelegate = self;
        // 设置识别类型
        ZBarImageScanner *scanner = reader.scanner;
        [scanner setSymbology:ZBAR_I25
                       config:ZBAR_CFG_ENABLE
                           to:0];
        reader.showsZBarControls = YES;
    
        // 推出扫码视图控制器
        [self presentViewController:reader animated:YES completion:nil];
    
    }
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    
        id results = [info objectForKey:ZBarReaderControllerResults];
        ZBarSymbol * symbol;
        for(symbol in results) {
    
            NSString *result = symbol.data;
            NSLog(@"%@",result);
        }
    
        // 退出拍照界面
        [picker dismissViewControllerAnimated:YES completion:nil];
    
    }
    
    @end

    注释:
    直接调用系统相机来实现二维码扫描虽然简单,但是存在极大的问题,那就是这样只能做全屏扫描,不能自定义二维码扫描的选取框。

    2.2 自定义扫描窗口

    项目中实现的二维码扫描功能我们发现都是可以设置扫描范围内的,下面我们来看一下如何自定义扫描的窗口。
    

    示例代码:

    #import "ViewController.h"
    #import "ZBarSDK.h"
    
    @interface ViewController ()<ZBarReaderViewDelegate>
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    #pragma mark -
    #pragma mark - 自定义扫描窗口
    - (IBAction)scan2Code:(id)sender {
    
        // 初始化扫描窗口
        ZBarReaderView *readerView = [[ZBarReaderView alloc] init];
    
        // 自定义大小
        readerView.frame = CGRectMake(self.view.frame.size.width/2-100, self.view.frame.size.height/2-100, 200, 200);
    
        // 设置代理
        readerView.readerDelegate = self;
    
        // 添加到父视图
        [self.view addSubview:readerView];
    
        // 二维码识别设置
        ZBarImageScanner *scanner = readerView.scanner;
        [scanner setSymbology:ZBAR_I25
                       config:ZBAR_CFG_ENABLE
                           to:0];
    
        // 开始扫描
        [readerView start];
    
    }
    
    #pragma mark - ZBarReaderViewDelegate
    - (void)readerView:(ZBarReaderView *)readerView didReadSymbols:(ZBarSymbolSet *)symbols fromImage:(UIImage *)image {
    
        // 获取扫描的标识
        ZBarSymbol *symbol = nil;
        for (symbol in symbols) {
    
            NSString *result = symbol.data;
    
            NSLog(@"%@",result);
        }
        // 停止扫描
        [readerView stop];
    }
    
    @end

    2.3 识别相册中的二维码图片:

    使用ZBarSDK可以直接选中相册中的二维码图片进行识别,这是系统自带的识别功能所不具备的。下面是识别相册中的二维码图片的实现方法。
    

    示例代码:

    #import "ViewController.h"
    #import "ZBarSDK.h"
    
    @interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    // 识别相册图片中的二维码
    - (IBAction)pick2Code:(id)sender {
    
        // 进入相册选中相册中的二维码图片
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
        imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;// 图片来源为相册
        imagePicker.delegate = self;
    
        // 进入相册
        [self presentViewController:imagePicker animated:YES completion:nil];
    
    }
    
    #pragma mark -
    #pragma mark - UIImagePickerControllerDelegate
    // 选中图片后调用该方法
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    
        // 获取选中的图片
        UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
        CGImageRef cgImage = image.CGImage;
    
        ZBarReaderController *reader = [[ZBarReaderController alloc] init];
        reader.delegate = self;
        ZBarSymbol *symbol = nil;
        for (symbol in [reader scanImage:cgImage]) {
    
            NSString *resulot = symbol.data;
            NSLog(@"%@",resulot);
        }
    
        // 识别结束后返回主界面
        [picker dismissViewControllerAnimated:YES completion:nil];
    }
    
    @end
    展开全文
  • Android Zxing二维码扫描图片拉伸、扫描框过小、扫描框扩大后(或不拉伸后闪退)闪退问题

    (一)Zxing二维码扫描框大小调整


    控制扫描框大小代码是在CameraManager类中

    google在CameraManager类中设置扫描框大小主要在getFramingRect()中:

      private static final int MIN_FRAME_WIDTH = 240;
      private static final int MIN_FRAME_HEIGHT = 240;
      private static final int MAX_FRAME_WIDTH = 480;
      private static final int MAX_FRAME_HEIGHT = 360;
      
    public Rect getFramingRect() {
        Point screenResolution = configManager.getScreenResolution();
        if (framingRect == null) {
          if (camera == null) {
            return null;
          }
        int width = screenResolution.x * 3 / 4;
          if (width < MIN_FRAME_WIDTH) {
            width = MIN_FRAME_WIDTH;
          } else if (width > MAX_FRAME_WIDTH) {
            width = MAX_FRAME_WIDTH;
          }
          int height = screenResolution.y * 3 / 4;
          if (height < MIN_FRAME_HEIGHT) {
            height = MIN_FRAME_HEIGHT;
          } else if (height > MAX_FRAME_HEIGHT) {
            height = MAX_FRAME_HEIGHT;
          }
         int leftOffset = (screenResolution.x - width) / 2;
         int topOffset = (screenResolution.y - height) / 2;
    
          framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
          Log.d(TAG, "Calculated framing rect: " + framingRect);
        }
        return framingRect;
      }



    我们修改 getFramingRect()这个方法,不再使用默认的固定大小,而是根据实际设备的屏幕大小设定

     public Rect getFramingRect() {
        Point screenResolution = configManager.getScreenResolution();
        if (framingRect == null) {
          if (camera == null) {
            return null;
          }
         DisplayMetrics metrics = context.getResources().getDisplayMetrics();
         int width = (int)(metrics.widthPixels * 0.6);
         int height = (int)(width * 0.9); 
         int leftOffset = (screenResolution.x - width) / 2;
         int topOffset = (screenResolution.y - height) / 2;
          framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
          Log.d(TAG, "Calculated framing rect: " + framingRect);
        }
        return framingRect;
      }


     
    
     
    

    以上方式可以实现扫描框扩大,但是部分机型会出现,扫描后闪退现象,原因是在 MipcaActivityCapture的handleDecode中向bundle中添加的bitmap过大,代码是bundle.putParcelable("bitmap", barcode);  handleDecode是用来处理扫描结果的,例如向调用MipcaActivityCapture的Activity回传扫描结果和扫描得到的bitmap。但bitmap不能过大超出内存限制就会奔溃。

    解决的办法:如果不需要显示扫描得到的图片,我们可以不将bitmap导入bundle,直接将bundle.putParcelable("bitmap", barcode)注释掉。

                         如果一定要获得bitmap,则需要在导入前将bitmap压缩

    (二)Zxing是google提供的二维码扫描工程

    扫描框默认是横屏的转换成竖屏后图片会出现拉伸现象

    解决的办法:

    Zxing  修改 CameraConfigurationManager.Java文件的

    void initFromCameraParameters(Camera camera)方法,在 Log.d(TAG, "Screen resolution: " + screenResolution);这句之后增加

    Point screenResolutionForCamera = new Point();  
            screenResolutionForCamera.x = screenResolution.x;  
            screenResolutionForCamera.y = screenResolution.y;  
            // preview size is always something like 480*320, other 320*480  
            if (screenResolution.x < screenResolution.y) {  
            screenResolutionForCamera.x = screenResolution.y;  
            screenResolutionForCamera.y = screenResolution.x;  
            }  
    同时把之后的代码如
    cameraResolution = getCameraResolution(parameters, screenResolution); 
    修改为
    cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);  
    经过如上操作后基本可以解决,图片拉伸的问题,但是部分机型会出现,扫描后闪退现象,原因和扩大扫描框后出现闪退的原因类似,基本是bitmap过大的原因。








    展开全文
  • 简单实现二维码扫描

    千次阅读 2016-08-05 15:38:42
    简单实现二维码扫描
  • 二维码扫描 在开发过程中,我们经常会遇到二维码扫描功能,下面是iOS原生扫描二维码的实现 类名:ScanViewController .h 文件 #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @...
  • 结构 <template> <view class="scan"> </view> </template> <script> let scan = null; export default { data() { return { flash: false, ... uni.chooseImage({
  • H5+ 二维码扫描功能

    万次阅读 2017-06-19 12:56:33
    二维码在生活中的使用越来越广泛,APP开发中,也越来越多的需求需要用到二维码的扫描功能,以下就针对h5+的二维码扫描功能做一些简单的介绍; 1. var bc = new plus.barcode.Barcode( id, filters, styles ); ...
  • 实现二维码扫描后跳转

    千次阅读 2016-06-30 18:57:49
    实现二维码扫描后跳转public void handleDecode(Result result, Bitmap barcode) { ////压缩图片保证不栈溢出,这两句是关键! Bitmap tempCode = barcode; barcode =scaleDownBitmap(tempCode, 64, ...
  • QR Code码,是一种矩阵二维码符号,这里的二维码样式: 这里使用网络框架,github上的依赖,只要使用几句话就能生成一个二维码的图像显示在页面上。
  • Android实现二维码扫描

    2017-12-05 14:22:55
    本文将讲解一下我最近写的一个快速集成二维码扫描库,这里需要说明的是其核心的实现扫描的功能,是通过调用ZXing库实现的。内部App中使用到了二维码扫描功能,但是网上找了一些关于二维码扫描的例子,只是我在集成的...
  • 使用ZXing实现二维码扫描

    万次阅读 2016-12-21 14:32:21
     其中刘超大神使用ZXing写了一个快速集成二维码扫描的工具类,实现其核心的实现扫描的功能。使用时通过调用二维码工具类,几行代码就可以实现二维码扫描的功能。  参考资料:   二维码工具类下载地址: ...
  • Android之二维码扫描和生成

    万次阅读 2017-03-18 17:23:09
    二维码生成和二维码扫描两个功能的实现,代码量少功能强大,是你最好的选择。
  • H5 移动端二维码扫描

    2021-08-31 16:07:52
    H5 移动端二维码扫描-附加扫描样式 依赖包jsQR 思路:通过浏览器获取视频流播放在video当中,然后设置定时器截取视频流绘制在canvas中,使用canvas获取到图片信息,再使用jsQR解析二维码。 由于开源二维码解析库识别...
  • ZXing实现二维码扫描

    2018-04-13 19:35:48
     其中刘超大神使用ZXing写了一个快速集成二维码扫描的工具类,实现其核心的实现扫描的功能。使用时通过调用二维码工具类,几行代码就可以实现二维码扫描的功能。 参考资料: 二维码工具类下载地址: ...
  • 内部App中使用到了二维码扫描功能,但是网上找了一些关于二维码扫描的例子,只是我在集成的时候发现通过android studio集成zxing二维码库不是特别方便,由于我就有了将其制作成标准库的想法,也就有了本文即快速集成...
  • Qt 之二维码扫描

    万次阅读 2016-07-05 17:25:10
    简述二维码(QR Code)是用某种特定的几何图形按一定规律在平面(二维方向)分布的黑白相间的图形记录数据符号信息的。是所有信息数据的一把钥匙。应用十分广泛,如:产品防伪/溯源、广告推送、网站链接、数据下载、...
  • 前言现在的应用中二维码扫描已经成为一个应用必不可少的功能,现在大部分Android二维码扫描都是基于zxing和Zbar,这文章就来介绍一下基于zxing的二维码扫描。先看下效果图 虽然现在的关于二维码的文章有很多,但是很...
  • Android手机客户端关于二维码扫描的源码,使用了zxing 3.1.1代码并对其进行了精简,支持低版本的sdk,实现了二维码和一维码的扫描、从图片解析一维码和二维码,闪光灯、调焦。
  • 内部App中使用到了二维码扫描功能,但是网上找了一些关于二维码扫描的例子,只是我在集成的时候发现通过android studio集成zxing二维码库不是特别方便,由于我就有了将其制作成标准库的想法,也就有了本文即快速集成...
  • 简介上一篇 Android实现二维码扫描功能(三)-闪光灯控制介绍了光线较弱情况下开启闪光灯来辅助二维码识别的方法。本篇我们介绍如何识别相册中的图片(含二维码)效果因为模拟器文件路径有问题(也可能是我没琢磨对...
  • 微信开发者工具调用二维码扫描接口wx.scanCode失败:errMsg: “scanCode:fail” 原因: 原因很简单:测试时选择的图片格式不对。 我保存了一张gif格式的二维码,调用二维码扫描接口测试时一直报错: 但是调用png...
  • iOS二维码扫描/识别

    千次阅读 2016-07-26 23:31:41
    本文提供了一套完整的二维码扫描与相册二维码识别的方案
  • 二维码扫描控件

    千次阅读 2017-08-28 16:58:09
    App上面有个二维码现在都是比较普遍了,方便很多更能,而二维码控件的实现也非常方便,所以加上二维码马上可以提高档次。而我使用的就是zxing。 zxing的使用:  1.导入bulid.gradle: compile '...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,739
精华内容 2,295
关键字:

二维码扫描失败图片