Skip to content

Commit

Permalink
Merge pull request #168 from abdelaziz-mahdy/imencode
Browse files Browse the repository at this point in the history
fix imencode interface
  • Loading branch information
rainyl authored Jul 22, 2024
2 parents 2bfb3b2 + 3cf58cc commit 4bbed3f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
25 changes: 17 additions & 8 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ class _MyAppState extends State<MyApp> {
}

// native resources are unsendable for isolate, so use raw data or encoded Uint8List and convert back
Future<(Uint8List, Uint8List)> heavyTask(Uint8List buffer) async => Isolate.run(() {
Future<(Uint8List, Uint8List)> heavyTask(Uint8List buffer) async =>
Isolate.run(() {
final im = cv.imdecode(buffer, cv.IMREAD_COLOR);
late cv.Mat gray, blur;
for (var i = 0; i < 1000; i++) {
gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY);
blur = cv.gaussianBlur(im, (7, 7), 2, sigmaY: 2);
}
return (cv.imencode(".png", gray), cv.imencode(".png", blur));
return (cv.imencode(".png", gray).$2, cv.imencode(".png", blur).$2);
});

Future<(cv.Mat, cv.Mat)> heavyTaskAsync(cv.Mat im) async {
Expand All @@ -66,12 +67,14 @@ class _MyAppState extends State<MyApp> {
ElevatedButton(
onPressed: () async {
final picker = ImagePicker();
final img = await picker.pickImage(source: ImageSource.gallery);
final img =
await picker.pickImage(source: ImageSource.gallery);
if (img != null) {
final path = img.path;
final mat = cv.imread(path);
print("cv.imread: width: ${mat.cols}, height: ${mat.rows}, path: $path");
final bytes = cv.imencode(".png", mat);
print(
"cv.imread: width: ${mat.cols}, height: ${mat.rows}, path: $path");
final (success, bytes) = cv.imencode(".png", mat);
// heavy computation
final (gray, blur) = await heavyTask(bytes);
setState(() {
Expand All @@ -83,16 +86,22 @@ class _MyAppState extends State<MyApp> {
),
ElevatedButton(
onPressed: () async {
final data = await DefaultAssetBundle.of(context).load("images/lenna.png");
final data = await DefaultAssetBundle.of(context)
.load("images/lenna.png");
final bytes = data.buffer.asUint8List();
// heavy computation
// final (gray, blur) = await heavyTask(bytes);
// setState(() {
// images = [bytes, gray, blur];
// });
final (gray, blur) = await heavyTaskAsync(cv.imdecode(bytes, cv.IMREAD_COLOR));
final (gray, blur) =
await heavyTaskAsync(cv.imdecode(bytes, cv.IMREAD_COLOR));
setState(() {
images = [bytes, cv.imencode(".png", gray), cv.imencode(".png", blur)];
images = [
bytes,
cv.imencode(".png", gray).$2,
cv.imencode(".png", blur).$2
];
});
},
child: const Text("Process"),
Expand Down
21 changes: 11 additions & 10 deletions lib/src/imgcodecs/imgcodecs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import 'dart:typed_data';
import 'package:ffi/ffi.dart';

import '../core/base.dart';
import '../core/error_code.dart';
import '../core/exception.dart';
import '../core/mat.dart';
import '../core/vec.dart';
import '../g/constants.g.dart';
Expand Down Expand Up @@ -59,23 +57,26 @@ bool imwrite(String filename, InputArray img, {VecI32? params}) {
///
/// For further details, please see:
/// http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga461f9ac09887e47797a54567df3b8b63
Uint8List imencode(
(bool, Uint8List) imencode(
String ext,
InputArray img, {
VecI32? params,
}) {
final buffer = calloc<cvg.VecUChar>();
final success = calloc<ffi.Bool>();
final pSuccess = calloc<ffi.Bool>();
final cExt = ext.toNativeUtf8().cast<ffi.Char>();

params == null
? cvRun(() => cimgcodecs.Image_IMEncode(cExt, img.ref, success, buffer))
: cvRun(() => cimgcodecs.Image_IMEncode_WithParams(cExt, img.ref, params.ref, success, buffer));
? cvRun(() => cimgcodecs.Image_IMEncode(cExt, img.ref, pSuccess, buffer))
: cvRun(() => cimgcodecs.Image_IMEncode_WithParams(cExt, img.ref, params.ref, pSuccess, buffer));
final success = pSuccess.value;
calloc.free(cExt);
if (!success.value) {
throw CvException(ErrorCode.StsError.code, msg: "imencode failed, check your params");
}
return VecUChar.fromPointer(buffer).toU8List();
calloc.free(pSuccess);

final vec = VecUChar.fromPointer(buffer);
final u8List = vec.toU8List(); // will copy data
vec.dispose();
return (success, u8List);
}

/// imdecode reads an image from a buffer in memory.
Expand Down
4 changes: 2 additions & 2 deletions test/imgcodecs_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ void main() async {
test("cv2.imencode, cv2.imdecode", () async {
final cvImage = cv.imread("test/images/circles.jpg", flags: cv.IMREAD_COLOR);
expect((cvImage.width, cvImage.height), (512, 512));
final buf = cv.imencode(".png", cvImage);
final (success, buf) = cv.imencode(".png", cvImage);
expect(buf.length, greaterThan(0));
await File("test/images_out/test_imencode.png").writeAsBytes(buf);
final params = [cv.IMWRITE_PNG_COMPRESSION, 9].i32;
final buf1 = cv.imencode(".png", cvImage, params: params);
final (success1, buf1) = cv.imencode(".png", cvImage, params: params);
expect(buf1.length, greaterThan(0));

final cvimgDecode = cv.imdecode(buf, cv.IMREAD_COLOR);
Expand Down

0 comments on commit 4bbed3f

Please sign in to comment.