Search code examples
c#.netimagebytedigital-persona-sdk

C# - Padding image bytes with white bytes to fill 512 x 512


I'm using Digital Persona SDK to scan fingerprints in wsq format, for requeriment I need 512 x 512 image, the SDK only export 357 x 392 image.

The sdk provide a method to compress captured image from device in wsq format and return a byte array that I can write to disk.

-I've tried to allocate a buffer of 262144 for 512 x 512 image.

-Fill the new buffer with white pixel data each byte to value 255.

-Copy the original image buffer into the new image buffer. The original image doesn’t need to be centered but it's important to make sure to copy without corrupting the image data.

To summarize I've tried to copy the old image into the upper right corner of the new image.

DPUruNet.Compression.Start();
DPUruNet.Compression.SetWsqBitrate(95, 0);

Fid capturedImage = captureResult.Data;

//Fill the new buffer with white pixel data each byte to value 255.
byte[] bytesWSQ512 = new byte[262144];
for (int i = 0; i < bytesWSQ512.Length; i++)
{
    bytesWSQ512[i] = 255;
}

//Compress capturedImage and get bytes (357 x 392)
byte[] bytesWSQ = DPUruNet.Compression.CompressRaw(capturedImage.Views[0].Width, capturedImage.Views[0].Height, 500, 8, capturedImage.Views[0].RawImage, CompressionAlgorithm.COMPRESSION_WSQ_NIST);

//Copy the original image buffer into the new image buffer
for (int i = 0; i < capturedImage.Views[0].Height; i++)
{
    for (int j = 0; j < capturedImage.Views[0].Width; j++)
    {
        bytesWSQ512[i * bytesWSQ512.Length + j ] = bytesWSQ[i * capturedImage.Views[0].Width + j];
    }
}
//Write bytes to disk
File.WriteAllBytes(@"C:\Users\Admin\Desktop\bytesWSQ512.wsq", bytesWSQ512);
DPUruNet.Compression.Finish();

When running that snippet I get IndexOutOfRangeException, I don't know if the loop or the calculation of indexes for new array are right.

Here is a representation of what I'm trying to do.

image


Solution

  • If someone is trying to achieve something like this or padding a raw image, I hope this will help.

    DPUruNet.Compression.
    DPUruNet.Compression.SetWsqBitrate(75, 0);
    Fid ISOFid = captureResult.Data;
    
    byte[] paddedImage = PadImage8BPP(captureResult.Data.Views[0].RawImage, captureResult.Data.Views[0].Width, captureResult.Data.Views[0].Height, 512, 512, 255);
    byte[] bytesWSQ512 = Compression.CompressRaw(512, 512, 500, 8, paddedImage, CompressionAlgorithm.COMPRESSION_WSQ_NIST);
    

    And the method to resize (pad) the image is:

    public byte[] PadImage8BPP(byte[] original, int original_width, int original_height, int desired_width, int desired_height, byte pad_color)
        {
            byte[] canvas_8bpp = new byte[desired_width * desired_height];
    
            for (int i = 0; i < canvas_8bpp.Length; i++)
                canvas_8bpp[i] = pad_color; //Fill background.  Note this type of fill will fail histogram checks.
    
            int clamp_y_begin = 0;
            int clamp_y_end = original_height;
            int clamp_x_begin = 0;
            int clamp_x_end = original_width;
    
            int pad_y = 0;
            int pad_x = 0;
    
            if (original_height > desired_height)
            {
                int crop_distance = (int)Math.Ceiling((original_height - desired_height) / 2.0);
                clamp_y_begin = crop_distance;
                clamp_y_end = original_height - crop_distance;
            }
            else
            {
                pad_y = (desired_height - original_height) / 2;
            }
    
            if (original_width > desired_width)
            {
                int crop_distance = (int)Math.Ceiling((original_width - desired_width) / 2.0);
                clamp_x_begin = crop_distance;
                clamp_x_end = original_width - crop_distance;
            }
            else
            {
                pad_x = (desired_width - original_width) / 2;
            }
    
            //We traverse the captured image (either whole image or subset)
            for (int y = clamp_y_begin; y < clamp_y_end; y++)
            {
                for (int x = clamp_x_begin; x < clamp_x_end; x++)
                {
                    byte image_pixel = original[y * original_width + x];
                    canvas_8bpp[(pad_y + y - clamp_y_begin) * desired_width + pad_x + x - clamp_x_begin] = image_pixel;
                }
            }
    
            return canvas_8bpp;
        }