Difference between revisions of "API/Write/Photos"

From Open Food Facts wiki
Jump to navigation Jump to search
Line 358: Line 358:
  
 
<pre>Test server: https://world.openfoodfacts.net/cgi/ingredients.pl</pre>
 
<pre>Test server: https://world.openfoodfacts.net/cgi/ingredients.pl</pre>
<pre>Live server: https://world.openfoodfacts.net/cgi/ingredients.pl</pre>
 
 
===== Values and output =====
 
===== Values and output =====
 
<pre>
 
<pre>
Line 366: Line 365:
 
</pre>
 
</pre>
  
 +
Example:
 +
<pre>
 +
ingredients.pl?code=13333560&id=ingredients_en&process_image=1&ocr_engine=tesseract
 +
</pre>
 
This will return JSON
 
This will return JSON
  

Revision as of 12:58, 28 June 2018

<Back to API/Write(Required reading)

Manipulating photos for a product

Understanding products and photos

  • Photos are the primary source of Open Food Facts.
  • We need good photos of the product, of its ingredients and nutrition table. (and for each language present on the packaging)
  • Please encourage your users to add as many photos as possible, even if the product is already complete (in that case, don't set them as default photos for front, ingredients, and nutrition)

Upload behaviour

If you upload an image (eg for front), the first one will be shown, the others will be saved but not displayed. Useful if you want to let your users take additional images that are neither front, ingredients or nutrition (eg: recycling instructions, labels…)

Understanding photos for multilingual products

Multilingual products have several photos based on languages present on the packaging. Just suffix the lang code to our examples to get or add the relevant language(s).

Adding photos for a product

  • Use the POST method on:
Test server: https://world.openfoodfacts.net/cgi/product_image_upload.pl
Live server: https://world.openfoodfacts.org/cgi/product_image_upload.pl

(remember to do tests on world.openfoodfacts.net - login and password: off )

Parameters
  • code: the barcode
  • imagefield: (front | ingredients | nutrition)
  • imgupload_front : your image file if imagefield:front
  • imgupload_ingredients: your image file if imagefield:ingredients
  • imgupload_nutrition: your image file if imagefield:nutrition


Example
curl --user off:off --form "imgupload_front=@Tacitus.jpg" --form code=1212121212 --form imagefield=front --form user_id=tacite  --form password=mypassword https://fr.openfoodfacts.net/cgi/product_image_upload.pl
Important
  • Content-Disposition: form-data; name=“imgupload_front”; filename=“front.png”
  • There must be a HTTP header "Content-Type: multipart/form-data" in the HTTP POST request.
  • The imageupload_(front|ingredients|nutrition) name, size and data needs to be encoded in the multipart/form-data format, usually your HTTP request library will do that for you.
  • All parameters need to be passed as POST parameters, do not put some in the URL.
  • 0048151623426 is a random barcode used only for demonstration purposes.

Getting a list of all available photos

You get a list of all available photos in the product JSON (both selected photos for all languages, and Raw photos (source images for the selected images and images that are not used)

Properties of a photo
  • id = 5
  • uploaded_t = 1474912158 (UNIX timestamp format)
  • uploader = tacinte (contributor slug)
  • sizes

100 "h":100, "w":75

  • 400

"h":400, "w":300

  • full

"w":3120, "h":4160

Properties of a selected photo
  • nutrition_fr
  • y1 = 151.8125
  • normalize":"true",
  • x2":"169.75",
  • rev":"13",
  • geometry":"1238x1238-527-1578"
  • sizes
  • 100

"h":100, "w":75

  • 200
  • 400

"h":400, "w":300

  • full

"w":3120, "h":4160

  • y2 = 270.8125
  • x1 = 50.75
  • angle = 0
  • white_magic = false
  • imgid = 4
      "images":{  
         "front_fr":{  
            "y2":"340.8125",
            "x1":"67.75",
            "angle":"0",
            "imgid":"5",
            "white_magic":"false",
            "x2":"245.75",
            "normalize":"true",
            "y1":"13.8125",
            "rev":"10",
            "geometry":"1851x3401-704-143",
            "sizes":{  
               "400":{  
                  "w":218,
                  "h":400
               },
               "full":{  
                  "h":3401,
                  "w":1851
               },
               "100":{  
                  "w":54,
                  "h":100
               },
               "200":{  
                  "h":200,
                  "w":109
               }
            }
         },
         "2":{  
            "sizes":{  
               "400":{  
                  "h":400,
                  "w":300
               },
               "full":{  
                  "h":4160,
                  "w":3120
               },
               "100":{  
                  "w":75,
                  "h":100
               }
            },
            "uploaded_t":"1474912149",
            "uploader":"tacinte"
         },
         "5":{  
            "uploaded_t":"1474912158",
            "uploader":"tacinte",
            "sizes":{  
               "100":{  
                  "h":100,
                  "w":75
               },
               "400":{  
                  "h":400,
                  "w":300
               },
               "full":{  
                  "w":3120,
                  "h":4160
               }
            }
         },
         "3":{  
            "uploaded_t":"1474912152",
            "uploader":"tacinte",
            "sizes":{  
               "full":{  
                  "w":3120,
                  "h":4160
               },
               "400":{  
                  "h":400,
                  "w":300
               },
               "100":{  
                  "h":100,
                  "w":75
               }
            }
         },
         "nutrition_fr":{  
            "y1":"151.8125",
            "normalize":"true",
            "x2":"169.75",
            "rev":"13",
            "geometry":"1238x1238-527-1578",
            "sizes":{  
               "full":{  
                  "w":1238,
                  "h":1238
               },
               "400":{  
                  "h":400,
                  "w":400
               },
               "100":{  
                  "w":100,
                  "h":100
               },
               "200":{  
                  "w":200,
                  "h":200
               }
            },
            "y2":"270.8125",
            "x1":"50.75",
            "angle":"0",
            "white_magic":"false",
            "imgid":"4"
         },
         "4":{  
            "sizes":{  
               "400":{  
                  "w":300,
                  "h":400
               },
               "full":{  
                  "h":4160,
                  "w":3120
               },
               "100":{  
                  "h":100,
                  "w":75
               }
            },
            "uploader":"tacinte",
            "uploaded_t":"1474912154"
         },
         "ingredients_fr":{  
            "y2":"248.8125",
            "x1":"82.75",
            "angle":"0",
            "white_magic":"false",
            "imgid":"3",
            "normalize":"true",
            "y1":"158.8125",
            "x2":"257.75",
            "rev":"12",
            "sizes":{  
               "full":{  
                  "w":1820,
                  "h":936
               },
               "400":{  
                  "h":206,
                  "w":400
               },
               "100":{  
                  "h":51,
                  "w":100
               },
               "200":{  
                  "h":103,
                  "w":200
               }
            },
            "geometry":"1820x936-860-1651"
         },
         "1":{  
            "sizes":{  
               "full":{  
                  "w":3120,
                  "h":4160
               },
               "400":{  
                  "h":400,
                  "w":300
               },
               "100":{  
                  "w":75,
                  "h":100
               }
            },
            "uploaded_t":"1474912148",
            "uploader":"tacinte"
         }
      },

Adding a photo to the list of all available photos

Getting the current global photo

Setting a new current global photo

Getting the current ingredients photo

Setting a new current ingredients photo

Getting the current nutrition photo

Setting a new current nutrition photo

Choosing the product by barcode

code=

Values:

Selecting a photo

imgid=

Values:

Rotating a photo

Test server: https://world.openfoodfacts.net/cgi/product_image_rotate.pl
Live server: https://world.openfoodfacts.org/cgi/product_image_rotate.pl
Values and output

Parameters:

imgid =
code = BARCODE
angle = Angle of the rotation - 90° increments
normalize = whether the source image should be normalized
white_magic = whether the source image should be "white magic"'d ( background removal)
function update_image(imagefield) {

	$('#crop_' + imagefield).attr("src","/cgi/product_image_rotate.pl?code=" + code + "&imgid=" + imagefield_imgid[imagefield]
		+ "&angle=" + angles[imagefield] + "&normalize=" + $("#normalize_" + imagefield).prop('checked')
		+ "&white_magic=" + $("#white_magic_" + imagefield).prop('checked')		);
	$('div[id="cropbuttonmsg_' + imagefield +'"]').hide();
}

Removing background on a photo ("White magic")

This will work best on photos with a white background. Best use case is to let user try it and give up if the result is not satisfying.

white_magic=

Values:

Color correction on a photo ("Normalize")

normalize=

Values:

Cropping a photo

This implies applying operations to a source image (not only cropping, but all the others if applicable). We start from a source image (defined by a barcode and incremental id), apply cropping parameters (x1, y1, x2, y2), additional operations (white_magic, normalize)

Test server: https://world.openfoodfacts.net/cgi/product_image_crop.pl
Live server: https://world.openfoodfacts.org/cgi/product_image_crop.pl
Values
code=BARCODE
id=
angle= Angle of the rotation
normalize = whether the source image should be normalized
white_magic = whether the source image should be white magiced ( background removal)
type = add
action = display
imgid =
x1= the X origin of the crop
y1=the Y origin of the crop
x2=the X end of the crop
y2=the Y end of the crop
Ignore me
$.post('/cgi/product_image_crop.pl',
{code: code, 
id: imagefield , 
imgid: imgid,				
x1:selection.x, 
y1:selection.y, 
x2:selection.x + selection.width, 
y2:selection.y + selection.height,
angle:angles[imagefield], 
normalize:$("#normalize_" + imagefield).prop('checked'), 
white_magic:$("#white_magic_" + imagefield).prop('checked') }, function(data) {
imagefield_url[imagefield] = data.image.display_url;
update_display(imagefield, false);
$('div[id="cropbutton_' + imagefield +'"]').show();
$('div[id="cropbuttonmsg_' + imagefield +'"]').html(Lang.image_saved);
$(document).foundation('equalizer', 'reflow');
}, 'json');
});		

Performing OCR on a photo

We start from a source image (defined by barcode and id) as selected for ingredients. We ask Product Opener to process it (process_image=1). Product Opener returns a JSON. Processing is done using Tesseract (3 on preprod). The result is often cripped with errors. Take steps to avoid direct copy pasting into the ingredients field by your users.

Test server: https://world.openfoodfacts.net/cgi/ingredients.pl
Values and output
code=code
id=imagefield
process_image=1

Example:

ingredients.pl?code=13333560&id=ingredients_en&process_image=1&ocr_engine=tesseract

This will return JSON

Ignore me
		$.post('/cgi/ingredients.pl',
				{ }, function(data) {
				
			if (data.status == 0) {
				$('div[id="ocrbuttondiv_' + imagefield +'"]').html(Lang.extracted_ingredients_ok);
				var ingredients_text_id = imagefield.replace("ingredients","ingredients_text");
				$("#" + ingredients_text_id).val(data.ingredients_text_from_image);
			}
			else {
				$('div[id="ocrbuttondiv_' + imagefield +'"]').html(Lang.extracted_ingredients_nok);
			}
			$(document).foundation('equalizer', 'reflow');
		}, 'json');