Skip to content

Commit

Permalink
feat: #494 - added OCR for packaging (#497)
Browse files Browse the repository at this point in the history
New files:
* `OcrPackagingResult.dart`: Result from OCR applied to packaging.
* `OcrPackagingResult.g.dart`: generated.

Impacted files:
* `OcrPackagingResult.dart`: mere refactoring in order to match the new `OcrPackagingResult` class.
* `openfoodfacts.dart`: new OCR method `extractPackaging`; refactored `extractIngredients` and fixed a bug.
  • Loading branch information
monsieurtanuki authored Jun 29, 2022
1 parent 1ee5184 commit 4c14abb
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 19 deletions.
24 changes: 13 additions & 11 deletions lib/model/OcrIngredientsResult.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@ import '../interface/JsonObject.dart';

part 'OcrIngredientsResult.g.dart';

/// Result from OCR applied to ingredients.
@JsonSerializable()
class OcrIngredientsResult extends JsonObject {
const OcrIngredientsResult({
this.status,
this.ingredientsTextFromImageOrig,
this.ingredientsTextFromImage,
});

factory OcrIngredientsResult.fromJson(Map<String, dynamic> json) =>
_$OcrIngredientsResultFromJson(json);

@override
Map<String, dynamic> toJson() => _$OcrIngredientsResultToJson(this);

final int? status;

@JsonKey(name: 'ingredients_text_from_image_orig')
final String? ingredientsTextFromImageOrig;

@JsonKey(name: 'ingredients_text_from_image')
final String? ingredientsTextFromImage;

const OcrIngredientsResult(
{this.status,
this.ingredientsTextFromImageOrig,
this.ingredientsTextFromImage});

factory OcrIngredientsResult.fromJson(Map<String, dynamic> json) =>
_$OcrIngredientsResultFromJson(json);

@override
Map<String, dynamic> toJson() => _$OcrIngredientsResultToJson(this);
}
28 changes: 28 additions & 0 deletions lib/model/OcrPackagingResult.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:json_annotation/json_annotation.dart';
import '../interface/JsonObject.dart';

part 'OcrPackagingResult.g.dart';

/// Result from OCR applied to packaging.
@JsonSerializable()
class OcrPackagingResult extends JsonObject {
const OcrPackagingResult({
this.status,
this.textFromImageOrig,
this.textFromImage,
});

factory OcrPackagingResult.fromJson(Map<String, dynamic> json) =>
_$OcrPackagingResultFromJson(json);

@override
Map<String, dynamic> toJson() => _$OcrPackagingResultToJson(this);

final int? status;

@JsonKey(name: 'packaging_text_from_image_orig')
final String? textFromImageOrig;

@JsonKey(name: 'packaging_text_from_image')
final String? textFromImage;
}
21 changes: 21 additions & 0 deletions lib/model/OcrPackagingResult.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 37 additions & 8 deletions lib/openfoodfacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:http/http.dart';
import 'package:openfoodfacts/interface/JsonObject.dart';
import 'package:openfoodfacts/model/KnowledgePanels.dart';
import 'package:openfoodfacts/model/OcrIngredientsResult.dart';
import 'package:openfoodfacts/model/OcrPackagingResult.dart';
import 'package:openfoodfacts/model/OrderedNutrients.dart';
import 'package:openfoodfacts/model/ProductFreshness.dart';
import 'package:openfoodfacts/model/ProductImage.dart';
Expand Down Expand Up @@ -699,26 +700,54 @@ class OpenFoodAPIClient {
OcrField ocrField = OcrField.GOOGLE_CLOUD_VISION,
QueryType? queryType,
}) async {
var ocrUri = UriHelper.getPostUri(
final Uri uri = UriHelper.getPostUri(
path: '/cgi/ingredients.pl',
queryType: queryType,
);
Map<String, String> queryParameters = <String, String>{
final Map<String, String> queryParameters = <String, String>{
'code': barcode,
'process_image': '1',
'id': 'ingredients_${language.code}',
'ocr_engine': OcrField.GOOGLE_CLOUD_VISION.key
'ocr_engine': ocrField.key
};
Response response = await HttpHelper().doPostRequest(
ocrUri,
final Response response = await HttpHelper().doPostRequest(
uri,
queryParameters,
user,
queryType: queryType,
);
return OcrIngredientsResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
);
}

OcrIngredientsResult result = OcrIngredientsResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)));
return result;
/// Extracts the text from packaging image with OCR.
static Future<OcrPackagingResult> extractPackaging(
final User user,
final String barcode,
final OpenFoodFactsLanguage language, {
final OcrField ocrField = OcrField.GOOGLE_CLOUD_VISION,
final QueryType? queryType,
}) async {
final Uri uri = UriHelper.getPostUri(
path: '/cgi/packaging.pl',
queryType: queryType,
);
final Map<String, String> queryParameters = <String, String>{
'code': barcode,
'process_image': '1',
'id': 'packaging_${language.code}',
'ocr_engine': ocrField.key
};
final Response response = await HttpHelper().doPostRequest(
uri,
queryParameters,
user,
queryType: queryType,
);
return OcrPackagingResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
);
}

/// Returns suggestions.
Expand Down

0 comments on commit 4c14abb

Please sign in to comment.