Escaneo de libros con escáner de código de barras C#

Categoría del blog: Barcode.NET

09.06.2025

El escaneo de libros con lectores de códigos de barras se está convirtiendo en una parte integral de la automatización de bibliotecas, librerías, archivos e instituciones educativas. Este enfoque agiliza el procesamiento de grandes colecciones, minimiza los errores contables y ofrece nuevas formas de interacción con el libro y el lector.

Principios de funcionamiento de un escáner de código de barras de software en el contexto de los libros

Un escáner de software es una solución de software especializada que reconoce y decodifica automáticamente los códigos de barras aplicados a los libros mediante cámaras, escáneres o dispositivos móviles. Su implementación permite organizar la contabilidad electrónica, la gestión de fondos y el procesamiento de transacciones de forma rápida y precisa, sin necesidad de introducir manualmente los datos.

El funcionamiento de un escáner de software se basa en el principio: un dispositivo (por ejemplo, una cámara o un escáner) lee una imagen de un código de barras de la portada o página de un libro, y el software descifra la información codificada en él (por ejemplo, ISBN) y transfiere estos datos a una biblioteca o sistema comercial para su posterior procesamiento.

Códigos de barras en libros

La mayoría de los libros publicados en las últimas décadas cuentan con un código de barras, generalmente un ISBN (Número Internacional Normalizado de Libro) en formato EAN-13 o un código QR (en publicaciones de nueva generación). Este código contiene un identificador único del libro, a menudo con información adicional sobre el ejemplar.

Uso de cámaras y escáneres

Un escáner de código de barras de software es una aplicación o biblioteca que puede reconocer códigos de barras utilizando tanto equipos especiales (escáneres, terminales) como cámaras web o dispositivos móviles, haciendo que el proceso sea lo más móvil y accesible posible.

Reconocimiento y procesamiento de datos

Los algoritmos de procesamiento de imágenes encuentran el código de barras en el libro, decodifican la información que contiene y la integran con catálogos, bases de datos y sistemas bibliotecarios, lo que garantiza una contabilidad rápida y precisa.

Etapas del escaneo de libros

El escaneo de libros con un escáner de código de barras de software incluye varias etapas consecutivas, cada una de las cuales es crucial para la precisión y eficiencia de los procesos de contabilidad, emisión y devolución de libros. Un ciclo de trabajo bien organizado puede reducir significativamente el tiempo de inventario, mejorar la calidad de los datos y optimizar el servicio en bibliotecas y librerías.

Preparación del equipo y el software

Antes de comenzar a escanear, debe asegurarse de que el dispositivo que utiliza sea compatible con el software y los estándares de código de barras seleccionados. A continuación:

Escaneo y reconocimiento del código de barras

En esta etapa, se lleva a cabo la lectura real del código de barras del libro:
El libro se coloca de manera que el código de barras sea claramente visible para la cámara o el escáner.

Integración con una biblioteca o sistema comercial

Después del reconocimiento exitoso, el escáner de software transfiere automáticamente los datos recibidos al sistema de información:

Almacenamiento, analítica y trabajo posterior con datos

Una vez que la información está en la base de datos, abre oportunidades para automatizar los procesos contables y analíticos:

Características y ventajas tecnológicas de un escáner de software moderno.

Un escáner de código de barras de software moderno cuenta con las siguientes soluciones tecnológicas:

Un software moderno de escáner de código de barras es una herramienta fundamental para cualquier biblioteca o librería que busque automatización, transparencia en la contabilidad y una mayor velocidad de servicio. Gracias a este software, el procesamiento de colecciones en papel pasa a un nivel digital moderno con costos mínimos y máximas ganancias.

Selección de una solución de software

Al elegir un escáner de código de barras de software para trabajar con libros, se recomienda considerar:

Las soluciones universales deben ser fáciles de integrar en la infraestructura de TI y soportar el trabajo en varios dispositivos: desde PC de escritorio hasta teléfonos móviles. Es aconsejable elegir productos con una interfaz sencilla, la capacidad de actualización y soporte técnico.

Perspectivas de desarrollo

Las tecnologías de escaneo de libros que utilizan lectores de códigos de barras de software continúan desarrollándose rápidamente. En un futuro cercano, se espera que los códigos de barras 2D (como DataMatrix y QR) se implementen más ampliamente, ya que pueden contener más información: enlaces a versiones electrónicas de libros, anotaciones, identificadores seguros.

La integración de los escáneres con servicios en la nube y bibliotecas digitales está creciendo, lo que permitirá el acceso automatizado a recursos en línea y servicios ampliados para los usuarios. En el futuro, también se espera la introducción de funciones inteligentes: análisis automático del estado del libro, generación de recomendaciones, así como el desarrollo de análisis de extremo a extremo y monitoreo del movimiento de fondos de la biblioteca.

Conclusión

Elegir una solución de software de escaneo de códigos de barras requiere considerar cuidadosamente diversos factores, como los formatos compatibles, la velocidad, las capacidades de integración y la facilidad de uso. Las perspectivas de desarrollo tecnológico abren nuevos horizontes para la automatización, aumentando la eficiencia de los sistemas bibliotecarios y mejorando el servicio a los usuarios.

VintaSoft, desarrollador del VintaSoft Barcode .NET SDK, simplifica significativamente la creación de un sistema de códigos de barras para bibliotecas. Esta potente herramienta admite una amplia gama de códigos de barras con distintos formatos, ofrece alta velocidad y precisión de escaneo, y se integra fácilmente con los sistemas bibliotecarios existentes. Con el SDK VintaSoft Barcode .NET, las bibliotecas podrán automatizar de forma rápida y eficiente todos los procesos relacionados con la contabilidad y el servicio de libros, mejorando la calidad del servicio y ahorrando recursos significativamente.


Aquí se muestra un código en C# que demuestra cómo reconocer un código de barras ISBN en una imagen capturada con una cámara:
/// <summary>
/// Reads barcode from a <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// <param name="bitmap">A bitmap with barcodes.</param>
public static void ReadIsbnBarcodesFromBitmap(System.Drawing.Bitmap bitmap)
{
    // create barcode reader
    using (Vintasoft.Barcode.BarcodeReader reader = new Vintasoft.Barcode.BarcodeReader())
    {
        // specify that reader must search for ISBN barcodes
        reader.Settings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.ISBN;

        // read barcodes from image
        Vintasoft.Barcode.IBarcodeInfo[] infos = Vintasoft.Barcode.GdiExtensions.ReadBarcodes(reader, bitmap);

        // if barcodes are not detected
        if (infos.Length == 0)
        {
            System.Console.WriteLine("No barcodes found.");
        }
        // if barcodes are detected
        else
        {
            // get information about extracted barcodes

            System.Console.WriteLine(string.Format("{0} barcodes found:", infos.Length));
            System.Console.WriteLine();
            for (int i = 0; i < infos.Length; i++)
            {
                Vintasoft.Barcode.IBarcodeInfo info = infos[i];
                System.Console.WriteLine(string.Format("[{0}:{1}]", i + 1, info.BarcodeType));
                System.Console.WriteLine(string.Format("Value:      {0}", info.Value));
                System.Console.WriteLine(string.Format("Region:     {0}", info.Region));
                System.Console.WriteLine();
            }
        }
    }
}



Aquí se muestra un código en C# que demuestra cómo capturar imágenes de una cámara DirectShow (SDK VintaSoft Imaging .NET) y reconocer códigos de barras ISBN en las imágenes capturadas (SDK VintaSoft Barcode .NET) en una aplicación WinForms:
public partial class IsbnBarcodeScannerForm : Form
{
    /// <summary>
    /// The camera barcode scanner.
    /// </summary>
    ImagingCameraBarcodeScanner _cameraBarcodeScanner;

    /// <summary>
    /// Initializes a new instance of the <see cref="IsbnBarcodeScannerForm"/> class.
    /// </summary>
    public IsbnBarcodeScannerForm()
    {
        InitializeComponent();

        _cameraBarcodeScanner = new ImagingCameraBarcodeScanner();
        _cameraBarcodeScanner.BarcodeScanner.FrameScanFinished += BarcodeScanner_FrameScanFinished;
        _cameraBarcodeScanner.ScanningException += CameraBarcodeScanner_ScanningException;

        _cameraBarcodeScanner.BarcodeScanner.ScannerSettings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.QR;
    }

    /// <summary>
    /// Starts the capturing of images from seleced device and recognition of barcodes in captured images.
    /// </summary>
    private void startButton_Click(object sender, EventArgs e)
    {
        textBox1.Text = "Scan Barcodes Types: " + _cameraBarcodeScanner.BarcodeScanner.ScannerSettings.ScanBarcodeTypes.ToString();

        _cameraBarcodeScanner.CaptureDevice = _cameraBarcodeScanner.CaptureDevices[0];
        _cameraBarcodeScanner.StartScanning();
    }

    /// <summary>
    /// Stops the capturing of images from seleced device and recognition of barcodes in captured images.
    /// </summary>
    private void stopButton_Click(object sender, EventArgs e)
    {
        textBox1.Text = "";

        _cameraBarcodeScanner.StopScanning();
    }

    /// <summary>
    /// Shows an error.
    /// </summary>
    private void CameraBarcodeScanner_ScanningException(object sender, Vintasoft.Imaging.ExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.ToString());
    }

    /// <summary>
    /// Handles the FrameScanFinished event of the BarcodeScanner.
    /// </summary>
    private void BarcodeScanner_FrameScanFinished(object sender, Vintasoft.Barcode.FrameScanFinishedEventArgs e)
    {
        if (e.FoundBarcodes.Length > 0)
            Invoke(new ShowRecognitionResultsDelegate(ShowRecognitionResults), new object[] { e.FoundBarcodes });
    }

    /// <summary>
    /// Shows barcode recognition results.
    /// </summary>
    private void ShowRecognitionResults(Vintasoft.Barcode.IBarcodeInfo[] barcodes)
    {
        StringBuilder result = new StringBuilder();

        foreach (Vintasoft.Barcode.IBarcodeInfo barcode in barcodes)
            result.AppendLine(string.Format("{0}: {1}", barcode.BarcodeType, barcode.Value));

        // show barcode recognition in text box
        textBox1.Text = result.ToString();
    }

    delegate void ShowRecognitionResultsDelegate(Vintasoft.Barcode.IBarcodeInfo[] barcodeInfo);
}


/// <summary>
/// Allows to capture images from DirectShow camera (VintaSoft Imaging .NET SDK) and recognize barcodes in captured images (VintaSoft Barcode .NET SDK).
/// </summary>
public class ImagingCameraBarcodeScanner : IDisposable
{

    #region Fields

    /// <summary>
    /// Monitor for capture devices.
    /// </summary>
    Vintasoft.Imaging.Media.ImageCaptureDevicesMonitor _captureDevicesMonitor;

    /// <summary>
    /// Image capture source for barcode recognition.
    /// </summary>
    Vintasoft.Imaging.Media.ImageCaptureSource _imageCaptureSource;

    #endregion



    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="ImagingCameraBarcodeScanner"/> class.
    /// </summary>
    public ImagingCameraBarcodeScanner()
    {
        _barcodeScanner = new Vintasoft.Barcode.CameraBarcodeScanner();
        _barcodeScanner.FrameScanException += BarcodeScanner_FrameScanException;
        _barcodeScanner.ScannerSettings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.ISBN;

        _captureDevicesMonitor = new Vintasoft.Imaging.Media.ImageCaptureDevicesMonitor();
        _captureDevicesMonitor.CaptureDevicesChanged += CaptureDevicesMonitor_CaptureDevicesChanged;

        if (!Vintasoft.Imaging.ImagingEnvironment.IsInDesignMode)
            _captureDevicesMonitor.Start();

        _imageCaptureSource = new Vintasoft.Imaging.Media.ImageCaptureSource();
        _imageCaptureSource.CaptureCompleted += ImageCaptureSource_CaptureCompleted;

    }

    #endregion



    #region Properties

    Vintasoft.Imaging.Media.ImageCaptureDevice _captureDevice;
    /// <summary>
    /// Gets or sets current capture device.
    /// </summary>
    public Vintasoft.Imaging.Media.ImageCaptureDevice CaptureDevice
    {
        get
        {
            return _captureDevice;
        }
        set
        {
            if (_captureDevice != value)
            {
                _captureDevice = value;

                UpdateCapureFormats();
            }
        }
    }

    ReadOnlyCollection<Vintasoft.Imaging.Media.ImageCaptureFormat> _captureFormats = null;
    /// <summary>
    /// Gets the available capture formats of current capture device.
    /// </summary>
    /// <seealso cref="CaptureDevice"/>
    public ReadOnlyCollection<Vintasoft.Imaging.Media.ImageCaptureFormat> CaptureFormats
    {
        get
        {
            return _captureFormats;
        }
    }

    /// <summary>
    /// Gets available capture devices.
    /// </summary>
    public ReadOnlyCollection<Vintasoft.Imaging.Media.ImageCaptureDevice> CaptureDevices
    {
        get
        {
            return Vintasoft.Imaging.Media.ImageCaptureDeviceConfiguration.GetCaptureDevices();
        }
    }

    Vintasoft.Barcode.CameraBarcodeScanner _barcodeScanner;
    /// <summary>
    /// Gets the barcode scanner.
    /// </summary>
    public Vintasoft.Barcode.CameraBarcodeScanner BarcodeScanner
    {
        get
        {
            return _barcodeScanner;
        }
    }

    /// <summary>
    /// Gets a value indicating whether barcode scanning is started.
    /// </summary>
    public bool IsStarted
    {
        get
        {
            return _imageCaptureSource.State == Vintasoft.Imaging.Media.ImageCaptureState.Started;
        }
    }

    #endregion



    #region Methods

    #region PUBLIC

    /// <summary>
    /// Starts the capturing of images from seleced device and recognition of barcodes in captured images.
    /// </summary>
    public void StartScanning()
    {
        try
        {
            if (CaptureDevice == null)
                throw new ArgumentNullException("CaptureDevice");

            if (CaptureFormats == null || CaptureFormats.Count == 0)
                throw new ArgumentNullException("CaptureFormats");

            if (_imageCaptureSource.State != Vintasoft.Imaging.Media.ImageCaptureState.Started)
            {
                if (CaptureDevice.DesiredFormat == null)
                    CaptureDevice.DesiredFormat = CaptureFormats[0];

                _barcodeScanner.StartScanning();

                _imageCaptureSource.CaptureDevice = _captureDevice;
                _imageCaptureSource.Start();
                _imageCaptureSource.CaptureAsync();

                OnScanningStart(EventArgs.Empty);
            }
        }
        catch (Exception ex)
        {
            OnScanningException(new Vintasoft.Imaging.ExceptionEventArgs(ex));
        }
    }

    /// <summary>
    /// Stops the capturing of images from seleced device and recognition of barcodes in captured images.
    /// </summary>
    public void StopScanning()
    {
        try
        {
            if (_imageCaptureSource.State != Vintasoft.Imaging.Media.ImageCaptureState.Stopped)
            {
                _barcodeScanner.StopScanning();
                _imageCaptureSource.Stop();

                OnScanningStop(EventArgs.Empty);
            }
        }
        catch (Exception ex)
        {
            OnScanningException(new Vintasoft.Imaging.ExceptionEventArgs(ex));
        }
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        _captureDevicesMonitor.CaptureDevicesChanged -= CaptureDevicesMonitor_CaptureDevicesChanged;
        _barcodeScanner.BarcodeReader.Dispose();
    }

    #endregion


    #region PROTECTED

    /// <summary>
    /// Raises the <see cref="CaptureDevicesChanged" /> event.
    /// </summary>
    /// <param name="args">The <see cref="ImageCaptureDevicesChangedEventArgs"/> instance containing the event data.</param>
    protected virtual void OnCaptureDevicesChanged(Vintasoft.Imaging.Media.ImageCaptureDevicesChangedEventArgs args)
    {
        if (CaptureDevicesChanged != null)
            CaptureDevicesChanged(this, args);
    }

    /// <summary>
    /// Raises the <see cref="ScanningException" /> event.
    /// </summary>
    /// <param name="args">The <see cref="ExceptionEventArgs"/> instance containing the event data.</param>
    protected virtual void OnScanningException(Vintasoft.Imaging.ExceptionEventArgs args)
    {
        if (ScanningException != null)
            ScanningException(this, args);
    }

    /// <summary>
    /// Raises the <see cref="ScanningStart" /> event.
    /// </summary>
    /// <param name="args">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected virtual void OnScanningStart(EventArgs args)
    {
        if (ScanningStart != null)
            ScanningStart(this, args);
    }

    /// <summary>
    /// Raises the <see cref="ScanningStop" /> event.
    /// </summary>
    /// <param name="args">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected virtual void OnScanningStop(EventArgs args)
    {
        if (ScanningStop != null)
            ScanningStop(this, args);
    }

    #endregion


    #region PRIVATE

    /// <summary>
    /// Handles the FrameScanException event of the BarcodeScanner control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="Vintasoft.Barcode.FrameScanExceptionEventArgs"/> instance containing the event data.</param>
    private void BarcodeScanner_FrameScanException(object sender, Vintasoft.Barcode.FrameScanExceptionEventArgs e)
    {
        OnScanningException(new Vintasoft.Imaging.ExceptionEventArgs(e.Exception));
    }

    /// <summary>
    /// Handles the CaptureCompleted event of the ImageCaptureSource.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="ImageCaptureCompletedEventArgs"/> instance containing the event data.</param>
    private void ImageCaptureSource_CaptureCompleted(object sender, Vintasoft.Imaging.Media.ImageCaptureCompletedEventArgs e)
    {
        try
        {
            // get captured image
            Vintasoft.Imaging.VintasoftImage image = e.GetCapturedImage();

            // recognize barcodes from captured image
            using (Vintasoft.Imaging.VintasoftBitmap bitmap = image.GetAsVintasoftBitmap())
                _barcodeScanner.ScanFrame(bitmap);

            // if image capturing is started
            if (_imageCaptureSource.State == Vintasoft.Imaging.Media.ImageCaptureState.Started)
            {
                // capture next image
                _imageCaptureSource.CaptureAsync();
            }
        }
        catch (Exception ex)
        {
            OnScanningException(new Vintasoft.Imaging.ExceptionEventArgs(ex));
        }
    }

    /// <summary>
    /// Handles the CaptureDevicesChanged event of the CaptureDevicesMonitor.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="ImageCaptureDevicesChangedEventArgs"/> instance containing the event data.</param>
    private void CaptureDevicesMonitor_CaptureDevicesChanged(object sender, Vintasoft.Imaging.Media.ImageCaptureDevicesChangedEventArgs e)
    {
        if (Array.IndexOf(e.RemovedDevices, CaptureDevice) >= 0)
        {
            StopScanning();
        }

        OnCaptureDevicesChanged(e);
    }

    /// <summary>
    /// Updates the capture formats.
    /// </summary>
    private void UpdateCapureFormats()
    {
        Vintasoft.Imaging.Media.ImageCaptureDevice device = CaptureDevice;
        if (device == null || device.SupportedFormats == null)
        {
            _captureFormats = null;
        }
        else
        {
            List<Vintasoft.Imaging.Media.ImageCaptureFormat> captureFormats = new List<Vintasoft.Imaging.Media.ImageCaptureFormat>();

            List<uint> imageCaptureFormatSizes = new List<uint>();
            for (int i = 0; i < device.SupportedFormats.Count; i++)
            {
                // if format has bit depth less or equal than 12 bit
                if (device.SupportedFormats[i].BitsPerPixel <= 12)
                {
                    // ignore formats with bit depth less or equal than 12 bit because they may cause issues on Windows 8
                    continue;
                }

                uint imageCaptureFormatSize = (uint)(device.SupportedFormats[i].Width | (device.SupportedFormats[i].Height << 16));
                if (!imageCaptureFormatSizes.Contains(imageCaptureFormatSize))
                {
                    imageCaptureFormatSizes.Add(imageCaptureFormatSize);

                    captureFormats.Add(device.SupportedFormats[i]);
                }
            }
            _captureFormats = captureFormats.AsReadOnly();
        }
    }

    #endregion

    #endregion



    #region Events

    /// <summary>
    /// Occurs when barcode scanning is started.
    /// </summary>
    public event EventHandler ScanningStart;

    /// <summary>
    /// Occurs when barcode scanning is stopped.
    /// </summary>
    public event EventHandler ScanningStop;

    /// <summary>
    /// Occurs when barcode scanning error occurs.
    /// </summary>
    public event EventHandler<Vintasoft.Imaging.ExceptionEventArgs> ScanningException;

    /// <summary>
    /// Occurs when <see cref="CaptureDevices"/> property is changed.
    /// </summary>
    public event EventHandler<Vintasoft.Imaging.Media.ImageCaptureDevicesChangedEventArgs> CaptureDevicesChanged;

    #endregion

}