Cómo leer y escribir códigos de barras en AWS Lambda

Chaknith Bin
Chaknith Bin
21 de noviembre, 2023
Actualizado 10 de octubre, 2024
Compartir:
This article was translated from English: Does it need improvement?
Translated
View the article in English
Amazon Lambda Architecture Logo related to Cómo leer y escribir códigos de barras en AWS Lambda

Este artículo de instrucciones ofrece una guía completa para configurar una función AWS Lambda utilizando IronBarcode. En esta guía, aprenderás cómo configurar IronBarcode para leer y escribir códigos de barras en un bucket de S3.

Instalación

Este artículo utilizará un bucket S3, por lo que se requiere el paquete AWSSDK.S3.

Usando IronBarcode Zip

Si estás utilizando IronBarcode ZIP, es esencial configurar la carpeta temporal.

var awsTmpPath = @"/tmp/";
IronBarCode.Installation.DeploymentPath = awsTmpPath;
var awsTmpPath = @"/tmp/";
IronBarCode.Installation.DeploymentPath = awsTmpPath;
Dim awsTmpPath = "/tmp/"
IronBarCode.Installation.DeploymentPath = awsTmpPath
$vbLabelText   $csharpLabel

El paquete Microsoft.ML.OnnxRuntime es necesario para leer códigos de barras. Aunque la escritura de códigos de barras funciona bien sin él, el modo predeterminado para la lectura depende del aprendizaje automático (ML). Si cambias a un modo de lectura que no utiliza ML, el paquete no es necesario.

Comience a usar IronBarcode en su proyecto hoy con una prueba gratuita.

Primer Paso:
green arrow pointer

Crear un proyecto AWS Lambda

Con Visual Studio, crear un AWS Lambda con contenedor es un proceso sencillo:

  • Instala el AWS Toolkit for Visual Studio
  • Seleccione un 'Proyecto AWS Lambda (.NET Core - C#)'
  • Seleccione un plano de " .NET 8 (Container Image)", luego seleccione "Finalizar".

    Seleccionar imagen de contenedor

Agregar dependencias de paquetes

La biblioteca IronBarcode en .NET 8 funciona en AWS Lambda sin necesidad de dependencias adicionales. Para configurarlo, actualice el Dockerfile del proyecto de la siguiente manera:


FROM public.ecr.aws/lambda/dotnet:8

# instalar los paquetes necesarios

RUN dnf update -y

WORKDIR /var/task

# Este comando COPY copia los artefactos de construcción del proyecto Lambda de .NET desde la máquina anfitriona hasta la imagen.

# El origen de la COPIA debe coincidir con el lugar donde el proyecto .NET Lambda publica sus artefactos de construcción.

Si se está construyendo la función Lambda

# con el AWS .NET Lambda Tooling, el interruptor `--docker-host-build-output-dir` controla dónde el proyecto .NET Lambda

# se construirá.

Los plantillas de proyecto Lambda de .NET tienen por defecto `--docker-host-build-output-dir`

# establecer en el archivo aws-lambda-tools-defaults.json a "bin/Release/lambda-publish".

#

# Alternativamente, se podría utilizar una compilación multietapa de Docker para construir el proyecto .NET Lambda dentro de la imagen.

# Para obtener más información sobre este enfoque, consulta el archivo README.md del proyecto.

COPIAR "bin/Release/lambda-publish" .

Modificar el código de FunctionHandler

Este ejemplo genera un código de barras EAN8, lo sube a un bucket de S3 y lee el código de barras recién creado. Al utilizar IronBarcode ZIP, configurar la carpeta temporal es crucial porque la biblioteca necesita permisos de escritura para copiar la carpeta de tiempo de ejecución desde los DLLs.

using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;
using IronBarCode;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace IronBarcodeZipAwsLambda;

public class Function
{
    private static readonly IAmazonS3 _s3Client = new AmazonS3Client(Amazon.RegionEndpoint.APSoutheast1);

    /// <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
    /// <returns></returns>
    public async Task FunctionHandler(ILambdaContext context)
    {
        var awsTmpPath = @"/tmp/";
        IronBarCode.Installation.DeploymentPath = awsTmpPath;

        IronBarCode.License.LicenseKey = "IRONBARCODE-MYLICENSE-KEY-1EF01";

        string filename = Guid.NewGuid().ToString();

        string bucketName = "deploymenttestbucket";
        string objectKey = $"IronBarcodeZip/{filename}.png";

        try
        {
            // Creating a barcode is as simple as:
            var myBarcode = BarcodeWriter.CreateBarcode("1212345", BarcodeWriterEncoding.EAN8);

            // Use pdfData (byte array) as needed
            context.Logger.LogLine($"Barocde created.");

            // Upload the PDF to S3
            await UploadPngToS3Async(bucketName, objectKey, myBarcode.ToPngBinaryData());

            context.Logger.LogLine($"Barocde uploaded successfully to {bucketName}/{objectKey}");

            var resultFromByte = BarcodeReader.Read(myBarcode.ToPngBinaryData());

            foreach (var item in resultFromByte)
            {
                // Log the read value out
                context.Logger.LogLine($"Barcode value is = {item.Value}");
            }
        }
        catch (Exception e)
        {
            context.Logger.LogLine($"[ERROR] FunctionHandler: {e.Message}");
        }
    }
    // Function to upload the PNG file to S3
    private async Task UploadPngToS3Async(string bucketName, string objectKey, byte[] pdfBytes)
    {
        using (var memoryStream = new MemoryStream(pdfBytes))
        {
            var request = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = objectKey,
                InputStream = memoryStream,
                ContentType = "image/png",
            };

            await _s3Client.PutObjectAsync(request);
        }
    }
}
using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;
using IronBarCode;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace IronBarcodeZipAwsLambda;

public class Function
{
    private static readonly IAmazonS3 _s3Client = new AmazonS3Client(Amazon.RegionEndpoint.APSoutheast1);

    /// <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
    /// <returns></returns>
    public async Task FunctionHandler(ILambdaContext context)
    {
        var awsTmpPath = @"/tmp/";
        IronBarCode.Installation.DeploymentPath = awsTmpPath;

        IronBarCode.License.LicenseKey = "IRONBARCODE-MYLICENSE-KEY-1EF01";

        string filename = Guid.NewGuid().ToString();

        string bucketName = "deploymenttestbucket";
        string objectKey = $"IronBarcodeZip/{filename}.png";

        try
        {
            // Creating a barcode is as simple as:
            var myBarcode = BarcodeWriter.CreateBarcode("1212345", BarcodeWriterEncoding.EAN8);

            // Use pdfData (byte array) as needed
            context.Logger.LogLine($"Barocde created.");

            // Upload the PDF to S3
            await UploadPngToS3Async(bucketName, objectKey, myBarcode.ToPngBinaryData());

            context.Logger.LogLine($"Barocde uploaded successfully to {bucketName}/{objectKey}");

            var resultFromByte = BarcodeReader.Read(myBarcode.ToPngBinaryData());

            foreach (var item in resultFromByte)
            {
                // Log the read value out
                context.Logger.LogLine($"Barcode value is = {item.Value}");
            }
        }
        catch (Exception e)
        {
            context.Logger.LogLine($"[ERROR] FunctionHandler: {e.Message}");
        }
    }
    // Function to upload the PNG file to S3
    private async Task UploadPngToS3Async(string bucketName, string objectKey, byte[] pdfBytes)
    {
        using (var memoryStream = new MemoryStream(pdfBytes))
        {
            var request = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = objectKey,
                InputStream = memoryStream,
                ContentType = "image/png",
            };

            await _s3Client.PutObjectAsync(request);
        }
    }
}
Imports Amazon.Lambda.Core
Imports Amazon.S3
Imports Amazon.S3.Model
Imports IronBarCode

' Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
<Assembly: LambdaSerializer(GetType(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))>

Namespace IronBarcodeZipAwsLambda

	Public Class [Function]
		Private Shared ReadOnly _s3Client As IAmazonS3 = New AmazonS3Client(Amazon.RegionEndpoint.APSoutheast1)

		''' <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
		''' <returns></returns>
		Public Async Function FunctionHandler(ByVal context As ILambdaContext) As Task
			Dim awsTmpPath = "/tmp/"
			IronBarCode.Installation.DeploymentPath = awsTmpPath

			IronBarCode.License.LicenseKey = "IRONBARCODE-MYLICENSE-KEY-1EF01"

			Dim filename As String = Guid.NewGuid().ToString()

			Dim bucketName As String = "deploymenttestbucket"
			Dim objectKey As String = $"IronBarcodeZip/{filename}.png"

			Try
				' Creating a barcode is as simple as:
				Dim myBarcode = BarcodeWriter.CreateBarcode("1212345", BarcodeWriterEncoding.EAN8)

				' Use pdfData (byte array) as needed
				context.Logger.LogLine($"Barocde created.")

				' Upload the PDF to S3
				Await UploadPngToS3Async(bucketName, objectKey, myBarcode.ToPngBinaryData())

				context.Logger.LogLine($"Barocde uploaded successfully to {bucketName}/{objectKey}")

				Dim resultFromByte = BarcodeReader.Read(myBarcode.ToPngBinaryData())

				For Each item In resultFromByte
					' Log the read value out
					context.Logger.LogLine($"Barcode value is = {item.Value}")
				Next item
			Catch e As Exception
				context.Logger.LogLine($"[ERROR] FunctionHandler: {e.Message}")
			End Try
		End Function
		' Function to upload the PNG file to S3
		Private Async Function UploadPngToS3Async(ByVal bucketName As String, ByVal objectKey As String, ByVal pdfBytes() As Byte) As Task
			Using memoryStream As New MemoryStream(pdfBytes)
				Dim request = New PutObjectRequest With {
					.BucketName = bucketName,
					.Key = objectKey,
					.InputStream = memoryStream,
					.ContentType = "image/png"
				}

				Await _s3Client.PutObjectAsync(request)
			End Using
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

Antes del bloque try, el destino del archivo se establece en el directorio IronBarcodeZip, con el nombre generado como un identificador único global (GUID). El método CreateBarcode se utiliza para generar el código de barras. Después, el array de bytes PNG se pasa al método Read para leer el código de barras. Esto demuestra que la función de AWS Lambda es capaz de leer códigos de barras.

El método Read también acepta un objeto BarcodeReaderOptions, que puedes personalizar para habilitar funciones como la lectura de múltiples códigos de barras, enfocar áreas específicas, usar procesamiento asíncrono y multihilo, aplicar filtros de corrección de imagen y mucho más.

Aumentar la memoria y el tiempo de espera

La cantidad de memoria asignada en la función Lambda variará según el tamaño de los documentos que se están procesando y la cantidad de documentos procesados simultáneamente. Como línea base, configure la memoria en 512 MB y el tiempo de espera en 300 segundos en aws-lambda-tools-defaults.json.


"function-memory-size" : 512,

"función-tiempo de espera" : 300

Cuando la memoria es insuficiente, el programa lanzará el error: 'Runtime exited with error: signal: killed.' Aumentar el tamaño de la memoria puede resolver este problema. Para más detalles, consulta el artículo de resolución de problemas: AWS Lambda - Runtime Exited Signal: Killed.

Publicar

Para publicar en Visual Studio, haga clic derecho en el proyecto y seleccione 'Publicar en AWS Lambda...', luego configure los ajustes necesarios. Puedes leer más sobre cómo publicar una Lambda en el sitio web de AWS.

¡Pruébalo!

Puedes activar la función Lambda ya sea a través de la consola Lambda o a través de Visual Studio.

Chaknith Bin
Ingeniero de software
Chaknith trabaja en IronXL e IronBarcode. Tiene una gran experiencia en C# y .NET, ayudando a mejorar el software y a apoyar a los clientes. Sus conocimientos de las interacciones con los usuarios contribuyen a mejorar los productos, la documentación y la experiencia general.