0

I am trying to parse a QR Code in a Windows Store-app using ZXing.Net, but when I try to run it using the latest version from their webpage it gives me a ArgumentNullException in BitmapLuminanceSource.Silverlight.cs on line 50

The line looks like this

var data = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(writeableBitmap.PixelBuffer, 0, (int)writeableBitmap.PixelBuffer.Length);

The WriteableBitmap is not null, so I do not what, what is null.

Can anybody help me?

It is from this method

public BitmapLuminanceSource(WriteableBitmap writeableBitmap)
   : base(writeableBitmap.PixelWidth, writeableBitmap.PixelHeight)
{
   var height = writeableBitmap.PixelHeight;
   var width = writeableBitmap.PixelWidth;
   var stride = width * 4;
   luminances = new byte[width * height];
   Color c;

#if NETFX_CORE
   var data = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(writeableBitmap.PixelBuffer, 0, (int)writeableBitmap.PixelBuffer.Length);
   for (int y = 0; y < height; y++)
   {
      int offset = y * stride;
      for (int x = 0, xl = 0; x < stride; x += 4, xl++)
      {
         c = Color.FromArgb(
            data[x + offset], 
            data[x + offset + 1], 
            data[x + offset + 2], 
            data[x + offset + 3]);
         luminances[y * width + xl] = (byte)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B + 0.01);
      }
   }
#else
   var pixels = writeableBitmap.Pixels;
   for (int y = 0; y < height; y++)
   {
      int offset = y * width;
      for (int x = 0; x < width; x++)
      {
         int srcPixel = pixels[x + offset];
         c = Color.FromArgb((byte)((srcPixel >> 0x18) & 0xff),
            (byte)((srcPixel >> 0x10) & 0xff),
            (byte)((srcPixel >> 8) & 0xff),
            (byte)(srcPixel & 0xff));
         luminances[offset + x] = (byte)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B + 0.01);
      }
   }
#endif
}

UPDATE

The WriteableBitmat is created using this code

// Get the File
var File = await FilePick.PickSingleFileAsync();

// Convert the File to a Bitmap
var Stream = await File.OpenAsync(FileAccessMode.Read);
var Bmp = new BitmapImage();
Bmp.SetSource(Stream);
var WBmp = new WriteableBitmap(Bmp.PixelWidth, Bmp.PixelHeight);
WBmp.SetSource(Stream);

By using Damir Arh's answer, the error is moved a bit to the following code

c = Color.FromArgb(
    data[x + offset], 
    data[x + offset + 1], 
    data[x + offset + 2], 
    data[x + offset + 3]);

Where I get an IndexOutOfRangeException, when

x = 580
xl = 145
offset = 31104
y = 36
height = 216
width = 216
stride = 864
data = {byte[31684]}

I can of course see why it is out of range, but I can not see how to fix it

It was fixed using Damir Arh's updated answer with Stream.Seek(0)

The87Boy
  • 877
  • 4
  • 14
  • 32
  • How can we know what is `null`? Did you debug your code? What is happening when your breakpoint cross this line? If you get `NullPointerException`, you are definitly try to access a part of some `null` value. – Soner Gönül Jan 07 '13 at 22:25
  • Yes, I set up a breakpoint the line before, so I hoped somebody else have had the same problem e.g. with `System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray` – The87Boy Jan 07 '13 at 22:29
  • Are you sure `writeableBitmap.PixelBuffer` is not `null` ? – Soner Gönül Jan 07 '13 at 22:32
  • When I set a breakpoint, it tells me the pixelbuffer is a Windows Runtime Object, and I can access the properties – The87Boy Jan 07 '13 at 22:34
  • I hate when single lines of code are posted when we can't possibly know what the other values are paste the relevant code for where you are using this line what method are you doing this in.. – MethodMan Jan 07 '13 at 22:35
  • @DJKRAZE I have added the full method now – The87Boy Jan 07 '13 at 22:40

1 Answers1

1

I made a quick port of the Silverlight example that's available from the project homepage and it worked:

var dlg = new FileOpenPicker();
dlg.FileTypeFilter.Add(".png");
var file = await dlg.PickSingleFileAsync();
if (file != null)
{
    currentBarcode = new WriteableBitmap(89, 89);
    using (var stream = await file.OpenReadAsync())
    {
        currentBarcode.SetSource(stream);
    }
    imgDecoderBarcode.Source = currentBarcode;
    var result = reader.Decode(currentBarcode);
    if (result != null)
    {
        txtDecoderType.Text = result.BarcodeFormat.ToString();
        txtDecoderContent.Text = result.Text;
    }
    else
    {
        txtDecoderType.Text = String.Empty;
        txtDecoderContent.Text = "No barcode found.";
    }
}

I also tried calling the offending line from the code you posted and there was no exception thrown:

var dlg = new FileOpenPicker();
dlg.FileTypeFilter.Add(".png");
var file = await dlg.PickSingleFileAsync();
if (file != null)
{
    currentBarcode = new WriteableBitmap(89, 89);
    using (var stream = await file.OpenReadAsync())
    {
        currentBarcode.SetSource(stream);
        var data = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(currentBarcode.PixelBuffer, 0, (int)currentBarcode.PixelBuffer.Length);
    }
}

The problem in your case is how you're creating the WriteableBitmap that is being passed to this method. Because you first load a Bitmap from the same stream you're already positioned at its end when you set it as the source for WritableBitmap. You need to reposition yourself to the beginning of the stream so that the data can be loaded once more:

// Convert the File to a Bitmap
var Stream = await File.OpenAsync(FileAccessMode.Read);
var Bmp = new BitmapImage();
Bmp.SetSource(Stream);
Stream.Seek(0);
var WBmp = new WriteableBitmap(Bmp.PixelWidth, Bmp.PixelHeight);
WBmp.SetSource(Stream);
Damir Arh
  • 17,637
  • 2
  • 45
  • 83
  • I created the WriteableBitmap using the code mentioned in the answer now. What is `imgDecoderBarcode` set to using your code? – The87Boy Jan 08 '13 at 19:27
  • @The87Boy `imgDecoderBarcode` is not relevant - it's just an `Image` control that show the image and can be safely commented out without affecting the rest of the code. The problem in your case is that you're loading two bitmaps from the same stream. I added the explanation to my answer. – Damir Arh Jan 08 '13 at 19:50