diff --git a/android/build.gradle b/android/build.gradle
index 631ea93..6af325a 100755
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,8 +1,22 @@
apply plugin: 'com.android.library'
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+ classpath 'com.google.gms:google-services:3.0.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
android {
- compileSdkVersion 23
- buildToolsVersion "23.0.1"
+ compileSdkVersion 25
+ buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 16
@@ -20,7 +34,8 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
- compile 'com.android.support:appcompat-v7:23.0.1'
+ compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.facebook.react:react-native:+'
- compile 'com.google.zxing:core:3.2.0'
+ compile 'com.google.zxing:core:+'
+ compile 'com.google.android.gms:play-services-vision:10.2.0'
}
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 0b6bfea..f3c7f75 100755
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -1,3 +1,9 @@
+
+
+
+
diff --git a/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImage.java b/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImage.java
index f873951..98d7dd5 100755
--- a/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImage.java
+++ b/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImage.java
@@ -1,7 +1,14 @@
package com.remobile.qrcodeLocalImage;
+import android.os.Environment;
+import android.util.Log;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.content.Context;
+import android.net.Uri;
+import android.database.Cursor;
+import android.provider.MediaStore;
+import android.util.SparseArray;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
@@ -10,22 +17,39 @@
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.RGBLuminanceSource;
+import com.google.zxing.LuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
+import com.google.android.gms.vision.barcode.*;
+import com.google.android.gms.vision.Frame;
+
+import java.io.Reader;
+import java.io.FileOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Hashtable;
+import static java.security.AccessController.getContext;
+
public class RCTQRCodeLocalImage extends ReactContextBaseJavaModule {
+
+ private ReactApplicationContext mReactContext;
+
+ private static final int RGB_MASK = 0x00FFFFFF;
+
public RCTQRCodeLocalImage(ReactApplicationContext reactContext) {
super(reactContext);
+ mReactContext = reactContext;
}
+ private static final String TAG = "QR";
+
@Override
public String getName() {
return "RCTQRCodeLocalImage";
@@ -33,46 +57,83 @@ public String getName() {
@ReactMethod
public void decode(String path, Callback callback) {
- Hashtable hints = new Hashtable();
- hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 设置二维码内容的编码
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true; // 先获取原大小
- options.inJustDecodeBounds = false; // 获取新的大小
-
- int sampleSize = (int) (options.outHeight / (float) 200);
-
- if (sampleSize <= 0)
- sampleSize = 1;
- options.inSampleSize = sampleSize;
- Bitmap scanBitmap = null;
- if (path.startsWith("http://")||path.startsWith("https://")) {
- scanBitmap = this.getbitmap(path);
- } else {
- scanBitmap = BitmapFactory.decodeFile(path, options);
- }
- if (scanBitmap == null) {
- callback.invoke("cannot load image");
- return;
- }
- int[] intArray = new int[scanBitmap.getWidth()*scanBitmap.getHeight()];
- scanBitmap.getPixels(intArray, 0, scanBitmap.getWidth(), 0, 0, scanBitmap.getWidth(), scanBitmap.getHeight());
-
- RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap.getWidth(), scanBitmap.getHeight(), intArray);
- BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
- QRCodeReader reader = new QRCodeReader();
try {
- Result result = reader.decode(bitmap, hints);
- if (result == null) {
- callback.invoke("image format error");
+ Uri mediaUri = Uri.parse(path);
+ String realPath = getRealPathFromUri(mReactContext, mediaUri);
+ Hashtable hints = new Hashtable();
+ hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 设置二维码内容的编码
+
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true; // 先获取原大小
+ options.inJustDecodeBounds = false; // 获取新的大小
+
+ int sampleSize = (int) (options.outHeight / (float) 200);
+
+ if (sampleSize <= 0)
+ sampleSize = 1;
+ options.inSampleSize = sampleSize;
+ Bitmap scanBitmap = null;
+ if (path.startsWith("http://")||path.startsWith("https://")) {
+ scanBitmap = this.getbitmap("https://instagram.fmvd1-1.fna.fbcdn.net/t51.2885-15/e35/18722826_1379673005443137_1152886071126654976_n.jpg");
} else {
- callback.invoke(null, result.toString());
+ scanBitmap = BitmapFactory.decodeFile(realPath, options);
}
+ if (scanBitmap == null) {
+ callback.invoke("cannot load image");
+ return;
+ }
+
+ Bitmap scanInvertBitmap = invert(scanBitmap);
+ // https://code.tutsplus.com/tutorials/reading-qr-codes-using-the-mobile-vision-api--cms-24680
+
+ int[] intArray = new int[scanInvertBitmap.getWidth()*scanInvertBitmap.getHeight()];
+ scanInvertBitmap.getPixels(intArray, 0, scanInvertBitmap.getWidth(), 0, 0, scanInvertBitmap.getWidth(), scanInvertBitmap.getHeight());
+ LuminanceSource source = new RGBLuminanceSource(scanInvertBitmap.getWidth(), scanInvertBitmap.getHeight(), intArray);
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ QRCodeReader reader = new QRCodeReader();
+
+ try {
+ Result result = reader.decode(bitmap, hints);
+ Log.d(TAG, "result - " + result);
+ if (result == null) {
+ callback.invoke("Image without qr");
+ } else {
+ callback.invoke(null, result.toString());
+ }
+
+ } catch (Exception e) {
+ Log.d(TAG, "Error - " + e);
+ callback.invoke("Decode error");
+ }
} catch (Exception e) {
- callback.invoke("decode error");
+ Log.d(TAG, "Error GENERIC - " + e);
+ callback.invoke("Life error");
}
}
+ public Bitmap invert(Bitmap original) {
+ // Create mutable Bitmap to invert, argument true makes it mutable
+ Bitmap inversion = original.copy(Bitmap.Config.ARGB_8888, true);
+
+ // Get info about Bitmap
+ int width = inversion.getWidth();
+ int height = inversion.getHeight();
+ int pixels = width * height;
+
+ // Get original pixels
+ int[] pixel = new int[pixels];
+ inversion.getPixels(pixel, 0, width, 0, 0, width, height);
+
+ // Modify pixels
+ for (int i = 0; i < pixels; i++)
+ pixel[i] ^= RGB_MASK;
+ inversion.setPixels(pixel, 0, width, 0, 0, width, height);
+ // Return inverted Bitmap
+// saveImage(inversion, "caro");
+ return inversion;
+ }
+
public static Bitmap getbitmap(String imageUri) {
Bitmap bitmap = null;
try {
@@ -90,6 +151,47 @@ public static Bitmap getbitmap(String imageUri) {
e.printStackTrace();
bitmap = null;
}
+
return bitmap;
}
+
+// private void saveImage(Bitmap finalBitmap, String image_name) {
+//
+// // Find the SD Card path
+// File filepath = Environment.getExternalStorageDirectory();
+//
+// // Create a new folder in SD Card
+// File myDir = new File(filepath.getAbsolutePath()
+// + "/WhatSappIMG/");
+// myDir.mkdirs();
+// String fname = "/Image-" + image_name+ ".jpg";
+// File file = new File(myDir, fname);
+// if (file.exists()) file.delete();
+// Log.d(TAG, "LOAD " + myDir + fname);
+// try {
+// FileOutputStream out = new FileOutputStream(file);
+// finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
+// out.flush();
+// out.close();
+// Log.d(TAG, "SaveImage ");
+// } catch (Exception e) {
+// e.printStackTrace();
+// Log.d(TAG, "Error saveImage - " + e);
+// }
+// }
+
+ public static String getRealPathFromUri(Context context, Uri contentUri) {
+ Cursor cursor = null;
+ try {
+ String[] proj = { MediaStore.Images.Media.DATA };
+ cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
+ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+ cursor.moveToFirst();
+ return cursor.getString(column_index);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
}
diff --git a/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImagePackage.java b/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImagePackage.java
index 01a6e3f..702921d 100755
--- a/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImagePackage.java
+++ b/android/src/main/java/com/remobile/qrcodeLocalImage/RCTQRCodeLocalImagePackage.java
@@ -18,11 +18,6 @@ public List createNativeModules(ReactApplicationContext reactConte
);
}
- @Override
- public List> createJSModules() {
- return Collections.emptyList();
- }
-
@Override
public List createViewManagers(ReactApplicationContext reactContext) {
return Arrays.asList();
diff --git a/ios/RCTQRCodeLocalImage/RCTQRCodeLocalImage.m b/ios/RCTQRCodeLocalImage/RCTQRCodeLocalImage.m
old mode 100755
new mode 100644
index 03453c7..5e63dbd
--- a/ios/RCTQRCodeLocalImage/RCTQRCodeLocalImage.m
+++ b/ios/RCTQRCodeLocalImage/RCTQRCodeLocalImage.m
@@ -10,44 +10,71 @@
#import
#import
#import "RCTQRCodeLocalImage.h"
+#import
@implementation RCTQRCodeLocalImage
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(decode:(NSString *)path callback:(RCTResponseSenderBlock)callback)
{
- UIImage *srcImage;
- if ([path hasPrefix:@"http://"] || [path hasPrefix:@"https://"]) {
- srcImage = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: path]]];
- } else {
- srcImage = [[UIImage alloc] initWithContentsOfFile:path];
- }
- if (nil==srcImage){
- NSLog(@"PROBLEM! IMAGE NOT LOADED\n");
- callback(@[RCTMakeError(@"IMAGE NOT LOADED!", nil, nil)]);
- return;
- }
- NSLog(@"OK - IMAGE LOADED\n");
- NSDictionary *detectorOptions = @{@"CIDetectorAccuracy": @"CIDetectorAccuracyHigh"};
- CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:detectorOptions];
- CIImage *image = [CIImage imageWithCGImage:srcImage.CGImage];
- NSArray *features = [detector featuresInImage:image];
- if (0==features.count) {
- NSLog(@"PROBLEM! Feature size is zero!\n");
- callback(@[RCTMakeError(@"Feature size is zero!", nil, nil)]);
- return;
- }
- CIQRCodeFeature *feature = [features firstObject];
- NSString *result = feature.messageString;
- NSLog(@"result: %@", result);
+ ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
+ {
+ ALAssetRepresentation *rep = [myasset defaultRepresentation];
+ float width = [rep dimensions].width;
+ float height = [rep dimensions].height;
+// CGImageRef iref = CGImageCreateWithImageInRect([rep fullResolutionImage], CGRectMake(width/2, 0, width/2, height));
+ CGImageRef iref = rep.fullScreenImage;
+ if (nil==rep){
+ NSLog(@"PROBLEM! IMAGE NOT LOADED\n");
+ callback(@[RCTMakeError(@"IMAGE NOT LOADED!", nil, nil)]);
+ return;
+ }
+
+// Write image to test
+
+// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+// NSString *fileName = [rep filename];
+// NSString *combined = [NSString stringWithFormat:@"ScreenShot - %@.png", fileName];
+// NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:combined];
+//
+// UIImage *currentImage = [UIImage imageWithCGImage:iref];
+// NSData *currentImageData = UIImagePNGRepresentation(currentImage);
+// [currentImageData writeToFile:filePath atomically:YES];
+//
+ NSLog(@"OK - IMAGE LOADED\n");
+ NSDictionary *detectorOptions = @{@"CIDetectorAccuracy": @"CIDetectorAccuracyHigh"};
+ CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:detectorOptions];
+ CIImage *image = [CIImage imageWithCGImage:iref];
+ NSArray *features = [detector featuresInImage:image];
+ if (0==features.count) {
+ NSLog(@"PROBLEM! Feature size is zero!\n");
+ callback(@[RCTMakeError(@"Feature size is zero!", nil, nil)]);
+ return;
+ }
+
+ CIQRCodeFeature *feature = [features firstObject];
+
+ NSString *result = feature.messageString;
+ NSLog(@"result: %@", result);
+
+ if (result) {
+ callback(@[[NSNull null], result]);
+ } else {
+ callback(@[RCTMakeError(@"QR Parse failed!", nil, nil)]);
+ return;
+ }
+ };
+
+ ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror){
+
+ //failed to get image.
+ };
- if (result) {
- callback(@[[NSNull null], result]);
- } else {
- callback(@[RCTMakeError(@"QR Parse failed!", nil, nil)]);
- return;
- }
+ ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
+ NSURL *myAssetUrl = [NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
+ [assetslibrary assetForURL:myAssetUrl resultBlock:resultblock failureBlock:failureblock];
}
+
@end