How to Read & Write Barcode on AWS Lambda
This how-to article provides a comprehensive guide to setting up an AWS Lambda function using IronBarcode. In this guide, you will learn how to configure IronBarcode to read from and write barcodes to an S3 bucket.
How to Read & Write Barcode on AWS Lambda
Installation
This article will use an S3 bucket, so the AWSSDK.S3 package is required.
Using IronBarcode Zip
If you are using IronBarcode ZIP, it is essential to set the temporary folder.
var awsTmpPath = @"/tmp/";
IronBarCode.Installation.DeploymentPath = awsTmpPath;
var awsTmpPath = @"/tmp/";
IronBarCode.Installation.DeploymentPath = awsTmpPath;
Dim awsTmpPath = "/tmp/"
IronBarCode.Installation.DeploymentPath = awsTmpPath
The Microsoft.ML.OnnxRuntime package is required for reading barcodes. While writing barcodes works fine without it, the default mode for reading relies on machine learning (ML). If you switch to a reading mode that doesn't use ML, the package is not needed.
Create an AWS Lambda Project
With Visual Studio, creating a containerized AWS Lambda is an easy process:
- Install the AWS Toolkit for Visual Studio
- Select an 'AWS Lambda Project (.NET Core - C#)'
- Select a '.NET 8 (Container Image)' blueprint, then select 'Finish'.
Add Package Dependencies
The IronBarcode library in .NET 8 works on AWS Lambda without needing extra dependencies. To set it up, update the project's Dockerfile as follows:
FROM public.ecr.aws/lambda/dotnet:8
# Install necessary packages
RUN dnf update -y
WORKDIR /var/task
# This COPY command copies the .NET Lambda project's build artifacts from the host machine into the image.
# The source of the COPY should match where the .NET Lambda project publishes its build artifacts. If the Lambda function is being built
# with the AWS .NET Lambda Tooling, the `--docker-host-build-output-dir` switch controls where the .NET Lambda project
# will be built. The .NET Lambda project templates default to having `--docker-host-build-output-dir`
# set in the aws-lambda-tools-defaults.json file to "bin/Release/lambda-publish".
#
# Alternatively Docker multi-stage build could be used to build the .NET Lambda project inside the image.
# For more information on this approach check out the project's README.md file.
COPY "bin/Release/lambda-publish" .
Modify the FunctionHandler Code
This example generates an EAN8 barcode, uploads it to an S3 bucket, and reads the newly created barcode. When using IronBarcode ZIP, configuring the temp folder is crucial because the library needs write permissions to copy the runtime folder from the 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);
/// <summary>
/// AWS Lambda Function Handler. It generates a barcode, uploads it to S3, and then reads it.
/// </summary>
/// <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
public async Task FunctionHandler(ILambdaContext context)
{
var awsTmpPath = @"/tmp/";
IronBarCode.Installation.DeploymentPath = awsTmpPath;
// Set your IronBarcode license key here
IronBarCode.License.LicenseKey = "IRONBARCODE-MYLICENSE-KEY-1EF01";
string filename = Guid.NewGuid().ToString();
string bucketName = "deploymenttestbucket";
string objectKey = $"IronBarcodeZip/{filename}.png";
try
{
// Creating a barcode with EAN8 encoding
var myBarcode = BarcodeWriter.CreateBarcode("1212345", BarcodeWriterEncoding.EAN8);
context.Logger.LogLine($"Barcode created.");
// Upload the PNG image of the barcode to the specified S3 bucket
await UploadPngToS3Async(bucketName, objectKey, myBarcode.ToPngBinaryData());
context.Logger.LogLine($"Barcode uploaded successfully to {bucketName}/{objectKey}");
// Read and log the barcode value from the PNG binary data
var resultFromByte = BarcodeReader.Read(myBarcode.ToPngBinaryData());
foreach (var item in resultFromByte)
{
context.Logger.LogLine($"Barcode value is = {item.Value}");
}
}
catch (Exception e)
{
context.Logger.LogLine($"[ERROR] FunctionHandler: {e.Message}");
}
}
/// <summary>
/// Uploads a PNG byte array to the specified S3 bucket.
/// </summary>
/// <param name="bucketName">The name of the S3 bucket.</param>
/// <param name="objectKey">The object key for the uploaded file in the bucket.</param>
/// <param name="pdfBytes">Byte array of the PNG to be uploaded.</param>
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);
/// <summary>
/// AWS Lambda Function Handler. It generates a barcode, uploads it to S3, and then reads it.
/// </summary>
/// <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
public async Task FunctionHandler(ILambdaContext context)
{
var awsTmpPath = @"/tmp/";
IronBarCode.Installation.DeploymentPath = awsTmpPath;
// Set your IronBarcode license key here
IronBarCode.License.LicenseKey = "IRONBARCODE-MYLICENSE-KEY-1EF01";
string filename = Guid.NewGuid().ToString();
string bucketName = "deploymenttestbucket";
string objectKey = $"IronBarcodeZip/{filename}.png";
try
{
// Creating a barcode with EAN8 encoding
var myBarcode = BarcodeWriter.CreateBarcode("1212345", BarcodeWriterEncoding.EAN8);
context.Logger.LogLine($"Barcode created.");
// Upload the PNG image of the barcode to the specified S3 bucket
await UploadPngToS3Async(bucketName, objectKey, myBarcode.ToPngBinaryData());
context.Logger.LogLine($"Barcode uploaded successfully to {bucketName}/{objectKey}");
// Read and log the barcode value from the PNG binary data
var resultFromByte = BarcodeReader.Read(myBarcode.ToPngBinaryData());
foreach (var item in resultFromByte)
{
context.Logger.LogLine($"Barcode value is = {item.Value}");
}
}
catch (Exception e)
{
context.Logger.LogLine($"[ERROR] FunctionHandler: {e.Message}");
}
}
/// <summary>
/// Uploads a PNG byte array to the specified S3 bucket.
/// </summary>
/// <param name="bucketName">The name of the S3 bucket.</param>
/// <param name="objectKey">The object key for the uploaded file in the bucket.</param>
/// <param name="pdfBytes">Byte array of the PNG to be uploaded.</param>
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)
''' <summary>
''' AWS Lambda Function Handler. It generates a barcode, uploads it to S3, and then reads it.
''' </summary>
''' <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
Public Async Function FunctionHandler(ByVal context As ILambdaContext) As Task
Dim awsTmpPath = "/tmp/"
IronBarCode.Installation.DeploymentPath = awsTmpPath
' Set your IronBarcode license key here
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 with EAN8 encoding
Dim myBarcode = BarcodeWriter.CreateBarcode("1212345", BarcodeWriterEncoding.EAN8)
context.Logger.LogLine($"Barcode created.")
' Upload the PNG image of the barcode to the specified S3 bucket
Await UploadPngToS3Async(bucketName, objectKey, myBarcode.ToPngBinaryData())
context.Logger.LogLine($"Barcode uploaded successfully to {bucketName}/{objectKey}")
' Read and log the barcode value from the PNG binary data
Dim resultFromByte = BarcodeReader.Read(myBarcode.ToPngBinaryData())
For Each item In resultFromByte
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
''' <summary>
''' Uploads a PNG byte array to the specified S3 bucket.
''' </summary>
''' <param name="bucketName">The name of the S3 bucket.</param>
''' <param name="objectKey">The object key for the uploaded file in the bucket.</param>
''' <param name="pdfBytes">Byte array of the PNG to be uploaded.</param>
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
Before the try block, the file destination is set to the IronBarcodeZip directory, with the name generated as a globally unique identifier (GUID). The CreateBarcode
method is used to generate the barcode. Afterward, the PNG byte array is passed to the Read
method to read the barcode. This demonstrates that the AWS Lambda function is capable of reading barcodes.
The Read
method also accepts a BarcodeReaderOptions object, which you can customize to enable features such as reading multiple barcodes, targeting specific areas, using asynchronous and multithreaded processing, applying image correction filters, and much more.
Increase Memory and Timeout
The amount of memory allocated in the Lambda function will vary based on the size of the documents being processed and the number of documents processed simultaneously. As a baseline, set the memory to 512 MB and the timeout to 300 seconds in aws-lambda-tools-defaults.json
.
{
"function-memory-size": 512,
"function-timeout": 300
}
When the memory is insufficient, the program will throw the error: 'Runtime exited with error: signal: killed.' Increasing the memory size can resolve this issue. For more details, refer to the troubleshooting article: AWS Lambda - Runtime Exited Signal: Killed.
Publish
To publish in Visual Studio, right-click on the project and select 'Publish to AWS Lambda...', then configure the necessary settings. You can read more about publishing a Lambda on the AWS website.
Try It Out!
You can activate the Lambda function either through the Lambda console or through Visual Studio.
Frequently Asked Questions
How do I set up IronBarcode on AWS Lambda?
To set up IronBarcode on AWS Lambda, download the C# library, create an AWS Lambda project using Visual Studio, modify the FunctionHandler code, configure the project, and deploy it. Ensure you have the necessary package dependencies like AWSSDK.S3 and Microsoft.ML.OnnxRuntime.
What packages are required for using IronBarcode on AWS Lambda?
You need the AWSSDK.S3 package for interacting with S3 buckets and the Microsoft.ML.OnnxRuntime package for reading barcodes using machine learning. If you are not using machine learning for reading, the latter is not required.
How can I modify the FunctionHandler code in AWS Lambda?
Modify the FunctionHandler code to generate a barcode, upload it to an S3 bucket, and read the barcode. Set the IronBarcode license key and configure the temp folder for IronBarcode ZIP usage.
How do I increase memory and timeout for an AWS Lambda function?
In the aws-lambda-tools-defaults.json file, set the function-memory-size to 512 MB and the function-timeout to 300 seconds. Adjust these settings based on your document processing needs.
How do I publish a Lambda function using Visual Studio?
Right-click on the project in Visual Studio, select 'Publish to AWS Lambda...', and configure the necessary settings. Follow AWS documentation for detailed steps on publishing.
How can I test the deployed AWS Lambda function?
You can activate the Lambda function through the AWS Lambda console or directly from Visual Studio to test its functionality.
What is the role of the Dockerfile in setting up IronBarcode on AWS Lambda?
The Dockerfile is used to update necessary packages and copy the .NET Lambda project's build artifacts into the image to set up IronBarcode on AWS Lambda.
Why is setting the temporary folder important when using IronBarcode ZIP?
Setting the temporary folder is crucial because IronBarcode ZIP requires write permissions to copy runtime folders from the DLLs, ensuring smooth operation on AWS Lambda.
Can I customize barcode reading using IronBarcode on AWS Lambda?
Yes, you can customize barcode reading using BarcodeReaderOptions to enable reading multiple barcodes, targeting specific areas, using asynchronous processing, and applying image correction filters.
What should I do if I encounter the 'Runtime exited with error: signal: killed' error?
This error indicates insufficient memory. Increase the memory allocation for the Lambda function in the aws-lambda-tools-defaults.json file to resolve this issue.