I have an application that is reading registration plates of an image. I have a simple UI where user can select image to scan using FilePicker.
So scenario where the problem occurs
- Select image A
- Scan image A --> Success
- Select image B
- Scan image B --> Success
- Select image A
- Scan image A --> Fail
Error I receive
System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI .'
I'm using WPF so Image component is using SourceImage
as source. I then do conversion. I couldn't find anything to convert SourceImage --> SoftwareBitmap
so I use Bitmap
as proxy
object
SourceImage --> Bitmap --> SoftwareImage (used by Microsoft OCR)
Code samples
File Picker
OpenFileDialog openFileDialog = new OpenFileDialog()
{
InitialDirectory = @"c:\Temp",
Filter = "Image files (*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png",
FilterIndex = 0,
RestoreDirectory = true,
Multiselect = false
};
if (openFileDialog.ShowDialog() == true)
{
img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
img.UriSource = new Uri(openFileDialog.FileName);
img.EndInit();
if(img != null)
{
ANPR_image.Source = img;
}
}
Convert to Bitmap
Bitmap bmp = new Bitmap(
source.PixelWidth,
source.PixelHeight,
System.Drawing.Imaging.PixelFormat.Format32bppArgb
);
BitmapData data = bmp.LockBits(
new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size),
ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
source.CopyPixels(
Int32Rect.Empty,
data.Scan0,
data.Height * data.Stride,
data.Stride);
bmp.UnlockBits(data);
return bmp;
Convert to SoftwareBitmap and OCR
using (Windows.Storage.Streams.InMemoryRandomAccessStream stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
{
if(newBitmap != null)
{
newBitmap.Save(stream.AsStream(), ImageFormat.Tiff); //choose the specific image format by your own bitmap source
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
using (SoftwareBitmap s_Bitmap = await decoder.GetSoftwareBitmapAsync())
{
try
{
result = await ocr.RecognizeAsync(s_Bitmap);
newBitmap.Dispose();
image.Dispose();
return result is null ? "" : result.Text;
}
catch(Exception e)
{
return "Error";
}
}
}
else
{
return "Image is null";
}
The error occurs here newBitmap.Save(stream.AsStream(), ImageFormat.Tiff); //choose the specific image format by your own bitmap source
I read online about this error and it seems there may be a lock somewhere but I can't figure out where... I tried disposing of all possible images, I wrapped everything with using
statements. Nothing works...
Any ideas, suggestion would be appreciated!
Thanks
CodePudding user response:
You may simplify your code by creating both bitmaps from a single MemoryStream
. Pass stream.AsRandomAccessStream()
to the BitmapDecoder.
var buffer = await File.ReadAllBytesAsync(openFileDialog.FileName);
using (var stream = new MemoryStream(buffer))
{
ANPR_image.Source = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
using (var randomAccessStream = stream.AsRandomAccessStream())
{
Windows.Graphics.Imaging.BitmapDecoder decoder =
await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(
randomAccessStream);
using (var softwareBitmap = await decoder.GetSoftwareBitmapAsync())
{
// ...
}
}
}