182 lines
7.5 KiB
Java
182 lines
7.5 KiB
Java
package com.example.lookifyv2;
|
|
|
|
import android.content.Intent;
|
|
import android.graphics.Bitmap;
|
|
import android.os.Bundle;
|
|
import android.util.Log;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
|
|
import com.google.zxing.BarcodeFormat;
|
|
import com.google.zxing.BinaryBitmap;
|
|
import com.google.zxing.DecodeHintType;
|
|
import com.google.zxing.LuminanceSource;
|
|
import com.google.zxing.MultiFormatReader;
|
|
import com.google.zxing.NotFoundException;
|
|
import com.google.zxing.RGBLuminanceSource;
|
|
import com.google.zxing.Result;
|
|
import com.google.zxing.common.HybridBinarizer;
|
|
|
|
import org.opencv.android.BaseLoaderCallback;
|
|
import org.opencv.android.LoaderCallbackInterface;
|
|
import org.opencv.android.OpenCVLoader;
|
|
import org.opencv.android.Utils;
|
|
import org.opencv.core.Mat;
|
|
import org.opencv.imgcodecs.Imgcodecs;
|
|
import org.opencv.imgproc.Imgproc;
|
|
|
|
import java.io.File;
|
|
import java.util.ArrayList;
|
|
import java.util.Hashtable;
|
|
import java.util.List;
|
|
|
|
import static org.opencv.imgproc.Imgproc.THRESH_BINARY;
|
|
|
|
public class Decode extends AppCompatActivity {
|
|
|
|
//Inicjalizacja logów OpenCV.
|
|
static final String TAG = "OCVSample::Activity";
|
|
|
|
String filePath;
|
|
Mat matPic;
|
|
|
|
//OpenCV domyślnie uruchamia się po onCreate co powoduje problemy - zapobiegamy więc temu, zapewniając, by metoda wykorzystująca OpenCV
|
|
//uruchamiała się dopiero po jego pomyślnym załadowaniu.
|
|
//https://docs.opencv.org/2.4/platforms/android/service/doc/BaseLoaderCallback.html
|
|
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
|
@Override
|
|
public void onManagerConnected(int status) {
|
|
switch (status) {
|
|
case LoaderCallbackInterface.SUCCESS: {
|
|
Log.i(TAG, "OpenCV loaded successfully");
|
|
decodePic(); //w praktyce tu się uruchamia cała reszta klasy
|
|
}
|
|
break;
|
|
default: {
|
|
super.onManagerConnected(status);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_decode);
|
|
}
|
|
|
|
private void decodePic() {
|
|
//Pobieranie adresu pliku przekazanego przez poprzednie activity.
|
|
Bundle extras = getIntent().getExtras();
|
|
filePath = extras.getString("takenPic");
|
|
|
|
//Obsługa sytuacji, w której nie ma dostępu do internetu - zrobione zdjęcie zostaje usunięte i następuje przejście do klasy
|
|
//odpowiedzialnej za błędy tej części aplikacji.
|
|
CheckInternet check = new CheckInternet();
|
|
if(!check.isOnline()){
|
|
File filefordeletion = new File(filePath);
|
|
filefordeletion.delete();
|
|
|
|
Intent intent_DecodeFail = new Intent(this, DecodeFail.class);
|
|
intent_DecodeFail.putExtra("status", "offline");
|
|
startActivity(intent_DecodeFail);
|
|
finish();
|
|
}
|
|
|
|
//Tworzenie mata ze zdjęcia i usuwanie zdjęcia.
|
|
matPic = Imgcodecs.imread(filePath);
|
|
File filefordeletion = new File(filePath);
|
|
filefordeletion.delete();
|
|
Mat matPicG = new Mat();
|
|
Mat matPicGB = new Mat();
|
|
Mat matPicGBT = new Mat();
|
|
|
|
//Zdjęcie zamieniane jest na czarno-biały odpowiednik.
|
|
//Na podstawie: Amgad Muhammad - OpenCV Android Programming By Example (43% e-booka).
|
|
Imgproc.cvtColor(matPic, matPicG, Imgproc.COLOR_RGB2GRAY);
|
|
|
|
//Usuwanie "noise'u" przy jednoczesnym zachowywaniu ostrych krawędzi za pomocą bilateralnego filtru.
|
|
//Na podstawie: Daniel Lelis Baggio - OpenCV 3.0 Computer Vision with Java (s. 52).
|
|
Imgproc.bilateralFilter(matPicG, matPicGB, 5, 75, 75);
|
|
|
|
//Zwiększanie kontrastu za pomocą thresholdu.
|
|
//Na podstawie: Salil Kapur, Nisarg Thakkar - Mastering OpenCV Android Application Programming (s. 19).
|
|
Imgproc.threshold(matPicGB, matPicGBT, 100, 255, THRESH_BINARY);
|
|
|
|
//Przygotowywanie mapy bitowej, którą przeskanuje ZXing w poszukiwaniu kodu.
|
|
Bitmap bMap = Bitmap.createBitmap(matPicGBT.width(), matPicGBT.height(), Bitmap.Config.ARGB_8888); //Zwykła mapa wbudowana w
|
|
//Javę/Android Studio.
|
|
Utils.matToBitmap(matPicGBT, bMap);
|
|
int[] intArray = new int[bMap.getWidth() * bMap.getHeight()];
|
|
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight()); //intArray otrzymuje dane o kolorach
|
|
//pikseli.
|
|
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray); //Zamienia różne formaty map na jedną
|
|
//spójną postać; pozwala wykonać nastepny krok.
|
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
|
|
|
//Zwiększanie efektywności wykrywania kodów.
|
|
Hashtable<DecodeHintType, Object> hints = new Hashtable<>();
|
|
|
|
List<Object> formats = new ArrayList<>();
|
|
formats.add(BarcodeFormat.AZTEC);
|
|
formats.add(BarcodeFormat.CODABAR);
|
|
formats.add(BarcodeFormat.CODE_39);
|
|
formats.add(BarcodeFormat.CODE_93);
|
|
formats.add(BarcodeFormat.CODE_128);
|
|
formats.add(BarcodeFormat.DATA_MATRIX);
|
|
formats.add(BarcodeFormat.EAN_8);
|
|
formats.add(BarcodeFormat.EAN_13);
|
|
formats.add(BarcodeFormat.ITF);
|
|
formats.add(BarcodeFormat.PDF_417);
|
|
formats.add(BarcodeFormat.QR_CODE);
|
|
formats.add(BarcodeFormat.RSS_14);
|
|
formats.add(BarcodeFormat.RSS_EXPANDED);
|
|
formats.add(BarcodeFormat.UPC_A);
|
|
formats.add(BarcodeFormat.UPC_E);
|
|
|
|
hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
|
|
hints.put(DecodeHintType.TRY_HARDER, true);
|
|
|
|
int reminder = 0; //Aplikacja zawsze jest trochę w przód z wykonywaniem kodu nawet po wywołaniu finish(), więc ta zmienna gwarantuje
|
|
//brak wyświetlania kodu, jeśli nie został on znaleziony.
|
|
|
|
//Szukanie kodu na wczytanym zdjęciu i podejmowanie odpowiednich działań w zależności od tego, czy został znaleziony, czy nie.
|
|
MultiFormatReader reader = new MultiFormatReader();
|
|
String contents = null;
|
|
try {
|
|
Result result = reader.decode(bitmap, hints);
|
|
contents = result.getText();
|
|
} catch (NotFoundException e) {
|
|
reminder = -1;
|
|
e.printStackTrace();
|
|
Intent intent_DecodeFail = new Intent(this, DecodeFail.class);
|
|
intent_DecodeFail.putExtra("status", "notfound");
|
|
startActivity(intent_DecodeFail);
|
|
finish();
|
|
}
|
|
if(reminder == 0) {
|
|
Toast.makeText(this, "Zidentyfikowany kod: " + contents,
|
|
Toast.LENGTH_SHORT).show();
|
|
Intent intent_Results = new Intent(this, Results.class);
|
|
intent_Results.putExtra("decodedcode", contents);
|
|
startActivity(intent_Results);
|
|
finish();
|
|
}
|
|
}
|
|
|
|
//Druga część potrzebna do ładowania OpenCV w odpowiednim momencie, czyli gdy aplikacja była zminimalizowana, a teraz zostaje z powrotem
|
|
//zmaksymalizowana.
|
|
@Override
|
|
protected void onResume() {
|
|
super.onResume();
|
|
if (!OpenCVLoader.initDebug()) {
|
|
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
|
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
|
} else {
|
|
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
|
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
|
}
|
|
}
|
|
} |