/// <summary> /// Process the input image and render into the output image /// </summary> /// <param name="imageIn">The input image</param> /// <param name="imageOut"> /// The output image, can be the same as <paramref name="imageIn"/>, in which case we will render directly into the input image. /// Note that if no bar codes are detected, <paramref name="imageOut"/> will remain unchanged. /// If bar codes are detected, we will draw the code and (rectangle) regions on top of the existing pixels of <paramref name="imageOut"/>. /// If the <paramref name="imageOut"/> is not the same object as <paramref name="imageIn"/>, it is a good idea to copy the pixels over from the input image before passing it to this function. /// </param> /// <returns>The messages that we want to display.</returns> public String ProcessAndRender(IInputArray imageIn, IInputOutputArray imageOut) { using (VectorOfMat points = new VectorOfMat()) { Stopwatch watch = Stopwatch.StartNew(); var barcodesFound = _barcodeDetector.DetectAndDecode(imageIn); watch.Stop(); for (int i = 0; i < barcodesFound.Length; i++) { Point[] contour = Array.ConvertAll(barcodesFound[i].Points, Point.Round); using (VectorOfVectorOfPoint vpp = new VectorOfVectorOfPoint(new Point[][] { contour })) { CvInvoke.DrawContours(imageOut, vpp, -1, RenderColor); } CvInvoke.PutText( imageOut, barcodesFound[i].DecodedInfo, Point.Round(barcodesFound[i].Points[0]), FontFace.HersheySimplex, 1.0, RenderColor ); } if (barcodesFound.Length == 0) { return(String.Format("No barcodes found (in {0} milliseconds)", watch.ElapsedMilliseconds)); } String[] barcodesTexts = Array.ConvertAll(barcodesFound, delegate(BarcodeDetector.Barcode input) { return(input.DecodedInfo); }); String allBarcodeText = String.Join(";", barcodesTexts); return(String.Format( "Barcodes found (in {1} milliseconds): {0}", allBarcodeText, watch.ElapsedMilliseconds)); } }