import 'dart:io'; import 'package:image/image.dart' as img; import 'package:imajviewer/services/crop_save_service.dart'; Future main() async { final tmp = Directory.systemTemp.createTempSync('crop_test'); final srcPath = '${tmp.path}/test.png'; final src = img.Image(width: 100, height: 50); void fill(int x, int y, int r, int g, int b) { for (var dy = 0; dy < 5; dy++) for (var dx = 0; dx < 5; dx++) src.setPixelRgb(x + dx, y + dy, r, g, b); } fill(0, 0, 255, 0, 0); // sol-ust: KIRMIZI fill(95, 0, 0, 255, 0); // sag-ust: YESIL fill(0, 45, 0, 0, 255); // sol-alt: MAVI fill(95, 45, 255, 255, 0); // sag-alt: SARI File(srcPath).writeAsBytesSync(img.encodePng(src)!); var fails = 0; void checkPix(String label, (int, int, int) px, int r, int g, int b) { int d(int a, int c) => (a - c).abs(); final ok = d(px.$1, r) <= 60 && d(px.$2, g) <= 60 && d(px.$3, b) <= 60; if (!ok) fails++; print('${ok ? 'OK ' : 'FAIL'} $label: got ${px.$1},${px.$2},${px.$3} want ~$r,$g,$b'); } // 1) Duz, fit, zoom yok: gorunen = kaynakin kendisi final outDir1 = '${tmp.path}/a'; Directory(outDir1).createSync(); final f1 = '${outDir1}/src.jpg'; File(f1).writeAsBytesSync(File(srcPath).readAsBytesSync()); final p1 = CropViewParams(w: 100, h: 50, vw: 100, vh: 50, tx: 0, ty: 0, sc: 1, angleDeg: 0, cx: 50, cy: 25, k: 1, ox: 0, oy: 0); final path1 = await CropSaveService.saveCrop(srcPath: f1, source: await CropSaveService.load(f1), vp: p1); final r1 = img.decodeImage(File(path1).readAsBytesSync())!; print('1) dims ${r1.width}x${r1.height} (100x50 beklenir)'); if (r1.width != 100 || r1.height != 50 || !path1.endsWith('.jpg')) fails++; checkPix('1) sol-ust', imgPx(r1, 2, 2), 255, 0, 0); checkPix('1) sag-alt', imgPx(r1, 97, 47), 255, 255, 0); // 2) 90 derece saat yelkolevi: cikti 50x100, orij sol-alt -> yeni sol-ust final out2 = '${tmp.path}/b'; Directory(out2).createSync(); final f2 = '$out2/src.jpg'; File(f2).writeAsBytesSync(File(srcPath).readAsBytesSync()); final p2 = CropViewParams(w: 100, h: 50, vw: 50, vh: 100, tx: 0, ty: 0, sc: 1, angleDeg: 90, cx: 25, cy: 50, k: 1, ox: -25, oy: 25); final path2 = await CropSaveService.saveCrop(srcPath: f2, source: await CropSaveService.load(f2), vp: p2); final r2 = img.decodeImage(File(path2).readAsBytesSync())!; print('2) dims ${r2.width}x${r2.height} (50x100 beklenir)'); if (r2.width != 50 || r2.height != 100) fails++; checkPix('2) sol-ust (orij sol-alt MAVI)', imgPx(r2, 2, 2), 0, 0, 255); checkPix('2) sag-ust (orij sol-ust KIRMIZI)', imgPx(r2, 47, 2), 255, 0, 0); checkPix('2) sol-alt (orij sag-alt SARI)', imgPx(r2, 2, 97), 255, 255, 0); checkPix('2) sag-alt (orij sag-ust YESIL)', imgPx(r2, 47, 97), 0, 255, 0); // 3) Zoom x2, 45 derece, fill: orneklenen alan ortada final out3 = '${tmp.path}/c'; Directory(out3).createSync(); final f3 = '$out3/src.jpg'; File(f3).writeAsBytesSync(File(srcPath).readAsBytesSync()); final p3 = CropViewParams(w: 100, h: 50, vw: 100, vh: 100, tx: 0, ty: 0, sc: 2, angleDeg: 45, cx: 50, cy: 50, k: 2, ox: 0, oy: -25); final path3 = await CropSaveService.saveCrop(srcPath: f3, source: await CropSaveService.load(f3), vp: p3); final r3 = img.decodeImage(File(path3).readAsBytesSync())!; print('3) dims ${r3.width}x${r3.height} (25x25 beklenir: zoom x2 + fill k=2 -> 4 src px/ekran px)'); if (r3.width != 25 || r3.height != 25) fails++; tmp.deleteSync(recursive: true); print(fails == 0 ? 'ALL PASS' : '$fails FAILURES'); exitCode = fails == 0 ? 0 : 1; } // jpeg kaybi oldugu icin 5x5 bolge ortalamasi al (int, int, int) imgPx(img.Image im, int x, int y) { int avg(int f) { var s = 0, n = 0; for (var dy = -2; dy <= 2; dy++) for (var dx = -2; dx <= 2; dx++) { final px = im.getPixelClamped(x + dx, y + dy); s += f == 0 ? px.r.toInt() : (f == 1 ? px.g.toInt() : px.b.toInt()); n++; } return s ~/ n; } return (avg(0), avg(1), avg(2)); }