step 19 : hapus loading, tambahkan grayscale upload foto, show foto kalau sudah di foto
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<application
|
||||
android:label="scanktpflutter"
|
||||
android:label="Ocr Ktp"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Scanktpflutter</string>
|
||||
<!-- <string>Scanktpflutter</string> -->
|
||||
<string>Ocr Ktp</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import '../../model/sex_model.dart';
|
||||
|
||||
import '../model/person_ktp_model.dart';
|
||||
import '../model/edit_person_model.dart';
|
||||
import 'base_repository.dart';
|
||||
|
||||
class ScanRepository extends BaseRepository {
|
||||
|
||||
77
lib/screen/scan/fungsiold.txt
Normal file
77
lib/screen/scan/fungsiold.txt
Normal file
@@ -0,0 +1,77 @@
|
||||
Future<File> rotateAndCropImage(File imageFile) async {
|
||||
Uint8List imageBytes = await imageFile.readAsBytes();
|
||||
img.Image? original = img.decodeImage(imageBytes);
|
||||
if (original == null) return imageFile;
|
||||
|
||||
img.Image rotated = img.bakeOrientation(original);
|
||||
|
||||
int width = rotated.width;
|
||||
int height = rotated.height;
|
||||
bool isPortrait = height > width;
|
||||
|
||||
int cropWidth, cropHeight;
|
||||
|
||||
if (isPortrait) {
|
||||
cropHeight = (height * 0.7).toInt();
|
||||
cropWidth = (cropHeight ~/ 1.59).toInt();
|
||||
} else {
|
||||
cropWidth = (width * 0.7).toInt();
|
||||
cropHeight = (cropWidth ~/ 1.59).toInt();
|
||||
}
|
||||
|
||||
int left = ((width - cropWidth) ~/ 2).toInt();
|
||||
int top = ((height - cropHeight) ~/ 2).toInt();
|
||||
|
||||
img.Image cropped = img.copyCrop(rotated,
|
||||
x: left, y: top, width: cropWidth, height: cropHeight);
|
||||
|
||||
File croppedFile = File('${imageFile.path}_cropped.jpg');
|
||||
await croppedFile.writeAsBytes(img.encodeJpg(cropped));
|
||||
|
||||
return croppedFile;
|
||||
}
|
||||
|
||||
Future<File> rotateImage(File imageFile) async {
|
||||
Uint8List bytes = await imageFile.readAsBytes();
|
||||
img.Image? image = img.decodeImage(bytes);
|
||||
|
||||
if (image == null) return imageFile;
|
||||
|
||||
img.Image rotated = img.copyRotate(image, angle: -90);
|
||||
|
||||
File rotatedFile = File('${imageFile.path}_rotated.jpg');
|
||||
await rotatedFile.writeAsBytes(img.encodeJpg(rotated));
|
||||
|
||||
return rotatedFile;
|
||||
}
|
||||
|
||||
Future<void> captureAndCropImage() async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
await initializeControllerFuture.value;
|
||||
|
||||
// Ambil gambar dari kamera
|
||||
final image = await cameraController.value!.takePicture();
|
||||
File cropped = await rotateAndCropImage(File(image.path));
|
||||
|
||||
// Rotate gambar setelah cropping
|
||||
File rotatedImage = await rotateImage(cropped);
|
||||
|
||||
// Simpan hasil yang sudah di-crop dan di-rotate
|
||||
capturedImage.value = image;
|
||||
croppedImage.value = rotatedImage;
|
||||
|
||||
// post ke BE
|
||||
Uint8List bytes = await croppedImage.value!.readAsBytes();
|
||||
String base64String = base64Encode(bytes);
|
||||
ref.read(uploadScanProvider.notifier).uploadScan(
|
||||
host: host,
|
||||
base64File: base64String,
|
||||
userId: userId,
|
||||
);
|
||||
} catch (e) {
|
||||
print("Error capturing image: $e");
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
@@ -122,13 +122,21 @@ class ScanScreen extends HookConsumerWidget {
|
||||
// Rotate gambar setelah cropping
|
||||
File rotatedImage = await rotateImage(cropped);
|
||||
|
||||
// Convert to grayscale
|
||||
Uint8List bytes = await rotatedImage.readAsBytes();
|
||||
img.Image? coloredImage = img.decodeImage(bytes);
|
||||
if (coloredImage != null) {
|
||||
img.Image grayscaleImage = img.grayscale(coloredImage);
|
||||
rotatedImage.writeAsBytesSync(img.encodeJpg(grayscaleImage));
|
||||
}
|
||||
|
||||
// Simpan hasil yang sudah di-crop dan di-rotate
|
||||
capturedImage.value = image;
|
||||
croppedImage.value = rotatedImage;
|
||||
|
||||
// post ke BE
|
||||
Uint8List bytes = await croppedImage.value!.readAsBytes();
|
||||
String base64String = base64Encode(bytes);
|
||||
Uint8List finalBytes = await croppedImage.value!.readAsBytes();
|
||||
String base64String = base64Encode(finalBytes);
|
||||
ref.read(uploadScanProvider.notifier).uploadScan(
|
||||
host: host,
|
||||
base64File: base64String,
|
||||
@@ -184,22 +192,6 @@ class ScanScreen extends HookConsumerWidget {
|
||||
return () {};
|
||||
}, [isLoadingUpload.value]);
|
||||
|
||||
// loading proses image useEffect
|
||||
useEffect(() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (isLoading.value == true) {
|
||||
snackbarWidget(
|
||||
context,
|
||||
'Sedang Proses Gambar...',
|
||||
snackbarType.warning,
|
||||
// Duration(seconds: 5),
|
||||
Duration(days: 1),
|
||||
);
|
||||
}
|
||||
});
|
||||
return () {};
|
||||
}, [isLoading.value]);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
@@ -229,7 +221,7 @@ class ScanScreen extends HookConsumerWidget {
|
||||
backgroundColor: Colors.black.withOpacity(0.5),
|
||||
body: Stack(
|
||||
children: [
|
||||
if (cameraController.value != null)
|
||||
if (cameraController.value != null && croppedImage.value == null)
|
||||
FutureBuilder<void>(
|
||||
future: initializeControllerFuture.value,
|
||||
builder: (context, snapshot) {
|
||||
@@ -240,19 +232,39 @@ class ScanScreen extends HookConsumerWidget {
|
||||
}
|
||||
},
|
||||
),
|
||||
// bingkai foto
|
||||
Positioned.fill(
|
||||
child: CustomPaint(
|
||||
painter: OverlayPainter(),
|
||||
// jika sudah ada foto
|
||||
if (croppedImage.value != null) ...[
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 300,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Image.file(
|
||||
croppedImage.value!,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
// bingkai foto
|
||||
Positioned.fill(
|
||||
child: CustomPaint(
|
||||
painter: OverlayPainter(),
|
||||
),
|
||||
),
|
||||
],
|
||||
// loading
|
||||
if (isLoading.value)
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(color: Colors.white),
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user