-
Notifications
You must be signed in to change notification settings - Fork 6
Description
i wrote a java program for android this library application, and want to visualize the analyzed image, however it seems not working, through looking at the catlog, the TransparencyArchive has been created, however sourceafis-visualization cannot create image from the TransparencyArchive, please help me, this is an important project for my graduation
// Nhập SourceAFIS Core
nhập com.machinezoo.sourceafis.FingerprintImage;
nhập com.machinezoo.sourceafis.FingerprintImageOptions;
nhập com.machinezoo.sourceafis.FingerprintTemplate;
nhập com.machinezoo.sourceafis.FingerprintTransparency;
// Nhập API minh bạch SourceAFIS
nhập com.machinezoo.sourceafis.transparency.TransparencyArchive;
nhập com.machinezoo.sourceafis.transparency.TransparencyBuffer;
nhập com.machinezoo.sourceafis.transparency.TransparencyKey;
nhập com.machinezoo.sourceafis.transparency.keys.*;
nhập com.machinezoo.sourceafis.transparency.types.SkeletonType;
// Nhập API trực quan hóa SourceAFIS
import com.machinezoo.sourceafis.visualization.TransparencyImage;
import com.machinezoo.sourceafis.visualization.TransparencyVisualizer;
lớp công khai MainActivity mở rộng AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 100;
// private static final String TAG = "SourceAFISDemo"; // Bỏ TAG
// Views
private ImageView imageViewInput, imageViewMinutiae, imageViewBinarized, imageViewSkeleton;
// Data and State
private Uri inputImageUri;
private byte[] inputImageData;
// Threading
private final ExecutorService backgroundExecutor = Executors.newSingleThreadExecutor();
private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
// Image Picker
private ActivityResultLauncher imagePickerLauncher;
@OverRide
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Ánh xạ Views
imageViewInput = findViewById(R.id.imageview_input);
imageViewMinutiae = findViewById(R.id.imageview_minutiae); // Sẽ hiển thị Output Template
imageViewBinarized = findViewById(R.id.imageview_binarized);
imageViewSkeleton = findViewById(R.id.imageview_skeleton);
Button buttonSelectImage = findViewById(R.id.button_select_image);
Button buttonAnalyze = findViewById(R.id.button_analyze);
// Khởi tạo ActivityResultLauncher
setupImagePicker();
// Thiết lập Listeners
buttonSelectImage.setOnClickListener(v -> checkPermissionAndPickImage());
buttonAnalyze.setOnClickListener(v -> performAnalysisAndVisualize());
}
@OverRide
protected void onDestroy() {
super.onDestroy();
backgroundExecutor.shutdown();
}
private void openImagePicker() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
try {
imagePickerLauncher.launch(intent);
} catch (Exception e) {
Toast.makeText(this, "Lỗi khi mở trình chọn ảnh. Hãy kiểm tra ứng dụng thư viện.", Toast.LENGTH_LONG).show();
}
}
private void loadImage(Uri imageUri, ImageView imageView) {
Bitmap bitmap;
InputStream inputStream = null;
try {
inputStream = getContentResolver().openInputStream(imageUri);
if (inputStream != null) {
inputImageData = readBytes(inputStream);
if (inputImageData != null && inputImageData.length > 0) {
BitmapFactory.Options options = new BitmapFactory.Options();
// Optional: decode bounds first if you need size info or sampling
// options.inJustDecodeBounds = true;
// BitmapFactory.decodeByteArray(inputImageData, 0, inputImageData.length, options);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeByteArray(inputImageData, 0, inputImageData.length, options);
if (bitmap != null) {
final Bitmap finalBitmap = bitmap;
mainThreadHandler.post(() -> {
imageView.setImageBitmap(finalBitmap);
});
clearResultImages();
} else {
handleImageLoadError("Không thể giải mã bitmap từ byte array.");
inputImageData = null;
}
} else {
handleImageLoadError("Đọc được 0 byte từ InputStream.");
inputImageData = null;
}
} else {
handleImageLoadError("Không thể lấy InputStream từ URI.");
inputImageData = null;
}
} catch (IOException e) {
handleImageLoadError("Lỗi IO khi đọc ảnh: " + e.getMessage());
inputImageData = null;
} catch (OutOfMemoryError oom) {
handleImageLoadError("Lỗi OutOfMemory khi tải ảnh.");
inputImageData = null;
} catch (SecurityException se) {
handleImageLoadError("Lỗi SecurityException khi truy cập URI.");
inputImageData = null;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
// Ignore close error or log if needed
}
}
}
}
private void handleImageLoadError(String message) {
// Display error to user
mainThreadHandler.post(() -> {
Toast.makeText(this, "Lỗi khi tải ảnh: " + message, Toast.LENGTH_SHORT).show();
if (imageViewInput != null) {
imageViewInput.setImageBitmap(null);
}
});
inputImageData = null;
clearResultImages();
}
private void clearResultImages() {
mainThreadHandler.post(() -> {
if (imageViewMinutiae != null) imageViewMinutiae.setImageBitmap(null);
if (imageViewBinarized != null) imageViewBinarized.setImageBitmap(null);
if (imageViewSkeleton != null) imageViewSkeleton.setImageBitmap(null);
});
}
private byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int len;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
private void performAnalysisAndVisualize() {
if (inputImageData == null || inputImageData.length == 0) {
Toast.makeText(this, "Vui lòng chọn ảnh vân tay hợp lệ trước", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, "Đang phân tích...", Toast.LENGTH_SHORT).show();
clearResultImages();
backgroundExecutor.execute(() -> {
TransparencyArchive archive;
// FingerprintTemplate template; // No longer directly needed after creation
try {
TransparencyBuffer buffer = new TransparencyBuffer();
try (FingerprintTransparency logger = buffer.open()) {
FingerprintImage fingerprintImage = new FingerprintImage(
inputImageData,
new FingerprintImageOptions().dpi(500)
);
// Tạo FingerprintTemplate để chạy pipeline và ghi dữ liệu vào buffer
new FingerprintTemplate(fingerprintImage);
} // logger tự đóng
archive = buffer.toArchive();
if (archive == null || archive.keys().isEmpty()) {
// Ném lỗi hoặc hiển thị thông báo nếu archive không hợp lệ
throw new IllegalStateException("TransparencyArchive không được tạo hoặc rỗng.");
}
// Chuẩn bị Keys
FilteredBinaryImageKey filteredBinaryKey = new FilteredBinaryImageKey();
ThinnedSkeletonKey thinnedSkeletonKeyRidges = new ThinnedSkeletonKey(SkeletonType.RIDGES);
OutputTemplateKey outputTemplateKey = new OutputTemplateKey();
// Tìm Visualizers
Optional<TransparencyVisualizer> filteredBinaryVizOpt = findVisualizerByKey(filteredBinaryKey);
Optional<TransparencyVisualizer> thinnedSkeletonVizOpt = findVisualizerByKey(thinnedSkeletonKeyRidges);
Optional<TransparencyVisualizer> outputTemplateVizOpt = findVisualizerByKey(outputTemplateKey);
// Gửi kết quả lên UI Thread
final TransparencyArchive finalArchive = archive;
mainThreadHandler.post(() -> {
// Hiển thị ảnh nhị phân
filteredBinaryVizOpt.ifPresentOrElse(
viz -> displayVisualization(viz, finalArchive, imageViewBinarized, "Ảnh nhị phân (Filtered)"),
() -> Toast.makeText(MainActivity.this, "Không thể tạo ảnh nhị phân", Toast.LENGTH_SHORT).show()
);
// Hiển thị khung xương
thinnedSkeletonVizOpt.ifPresentOrElse(
viz -> displayVisualization(viz, finalArchive, imageViewSkeleton, "Khung xương (Ridges Thinned)"),
() -> Toast.makeText(MainActivity.this, "Không thể tạo ảnh khung xương", Toast.LENGTH_SHORT).show()
);
// Hiển thị đặc trưng đầu ra
outputTemplateVizOpt.ifPresentOrElse(
viz -> displayVisualization(viz, finalArchive, imageViewMinutiae, "Đặc trưng đầu ra (Output Template)"),
() -> Toast.makeText(MainActivity.this, "Không thể tạo ảnh đặc trưng", Toast.LENGTH_SHORT).show()
);
Toast.makeText(MainActivity.this, "Hoàn thành!", Toast.LENGTH_SHORT).show();
});
} catch (Exception e) {
// Hiển thị lỗi chung cho người dùng trên UI thread
mainThreadHandler.post(() -> {
Toast.makeText(MainActivity.this, "Lỗi xử lý vân tay: " + e.getClass().getSimpleName(), Toast.LENGTH_LONG).show();
clearResultImages();
});
// Ghi log lỗi ở đây nếu cần debug sau này (nhưng đã yêu cầu bỏ log)
e.printStackTrace(); // Tạm thời giữ lại để debug nếu cần
} catch (OutOfMemoryError oom) {
mainThreadHandler.post(() -> {
Toast.makeText(MainActivity.this, "Lỗi bộ nhớ khi xử lý vân tay", Toast.LENGTH_LONG).show();
clearResultImages();
});
oom.printStackTrace(); // Tạm thời giữ lại
}
});
}
private Optional findVisualizerByKey(TransparencyKey<?> targetKey) {
return TransparencyVisualizer.all().stream()
.filter(viz -> viz.key().equals(targetKey))
.findFirst();
// Nếu không tìm thấy, Optional sẽ là empty, xử lý trong luồng gọi
}
private void displayVisualization(TransparencyVisualizer visualizer,
final TransparencyArchive archive,
ImageView imageView,
String description) { // Description chỉ còn dùng cho Toast lỗi
Bitmap bitmap = null;
try {
// Kiểm tra key có thể bỏ qua nếu chỉ hiển thị lỗi chung
// boolean keyExists = archive.contains(visualizer.key());
TransparencyImage transparencyImage = visualizer.visualize(archive);
if (transparencyImage == null) {
throw new NullPointerException("TransparencyImage là null cho: " + description);
}
byte[] imageBytes = transparencyImage.bytes();
if (imageBytes == null || imageBytes.length == 0) {
throw new IOException("Dữ liệu ảnh rỗng cho: " + description);
}
bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
throw new IOException("Không thể giải mã Bitmap cho: " + description);
}
} catch (Exception e) {
imageView.setImageBitmap(null); // Xóa ảnh cũ nếu lỗi
Toast.makeText(this, "Lỗi khi tạo ảnh " + description, Toast.LENGTH_SHORT).show();
e.printStackTrace(); // Tạm thời giữ lại
} catch (OutOfMemoryError oom) {
imageView.setImageBitmap(null);
Toast.makeText(this, "Lỗi bộ nhớ khi tạo ảnh " + description, Toast.LENGTH_SHORT).show();
oom.printStackTrace(); // Tạm thời giữ lại
}
}
} // Kết thúc lớp MainActivity`