0

I have some timer that elapsed 180 ~ 200 ms. If timer elapsed make Byte Array (size is 3840 * 1250) and generate event. and then, event receivers are create bitmap and update image to pictureboxes. But, I have a probleam Fatal Execution Engine Error in My Method (CreateBitmapFromByteSource(w, h, source).

Exception is occured when BitmapEncoder call Save method..

Please Help me...

Timer Elapsed Body

private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        System.Threading.Thread tr = new System.Threading.Thread(() => 
        {
            int trID = System.Threading.Thread.CurrentThread.ManagedThreadId;

            byte[] source1 = BitmapUtilities.GenerateSourceData(this._sourceDataLength);
            byte[] srouce2 = BitmapUtilities.GenerateSourceData(this._sourceDataLength);

            if (UpdateSourceData != null)
                UpdateSourceData(this, new ImageGenerateEventArgs(Count, this._width, this._height, source1, srouce2));
        });
        tr.IsBackground = true;
        tr.Start();
    }

Event Receiver Body

private void ImageViewer_UpdateSourceData(object sender, ImageGenerateEventArgs args)
    {
        Action lambda = () => 
        {
            int trID = System.Threading.Thread.CurrentThread.ManagedThreadId;
            Bitmap bitmap = BitmapUtilities.CreateBitmapFromByteSource(args.W, args.H, args.S1);
            bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);

            if (this.pictureBox1.Image != null)
                this.pictureBox1.Image.Dispose();

            this.pictureBox1.Image = bitmap;
            this.pictureBox1.Update();
            bitmap.Dispose();

            bitmap = BitmapUtilities.CreateBitmapFromByteSource(args.W, args.H, args.S2);
            bitmap.RotateFlip(RotateFlipType.Rotate180FlipX);

            if (this.pictureBox2.Image != null)
                this.pictureBox2.Image.Dispose();

            this.pictureBox2.Image = bitmap;
            this.pictureBox2.Update();

            bitmap.Dispose();
        };

        if (this.InvokeRequired)
            this.Invoke(lambda);
        else
            lambda();
    }

CreateBitmapFromByteSource(w, h, source) Body

static public Bitmap CreateBitmapFromByteSource(int width, int height, byte[] byteSource)
    {
        Bitmap image;
        BitmapSource src;
        try
        {
            src = BitmapSource.Create(width, height, 96, 96, System.Windows.Media.PixelFormats.Gray8, null, byteSource, width);
            using (MemoryStream ms = new MemoryStream())
            {
                BitmapEncoder enc = new BmpBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(src));
                enc.Save(ms);
                image = new System.Drawing.Bitmap(ms);
            }

            return image;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
            return null;
        }
    }
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Why are you first creating a WPF BitmapSource, only to convert it into a WinForms Bitmap? – Clemens Jul 24 '19 at 07:31
  • Clemens, I'm working on a program that converts byte arrays into grayscale images and shows them to Winform. However, in order to ensure fast speed, we found the WFP's BitmapEncoder while looking in many ways. That's why we used BitmapSource to use BitmapEncoder. – Dongyeop Choi Jul 24 '19 at 07:38
  • Weather Vane, I tagging C#... – Dongyeop Choi Jul 24 '19 at 07:39
  • But you wouldn't need BitmapEncoder at all if you would directly create a Bitmap from a raw pixel buffer. That's certainly faster than first creating a BitmapSource from raw pixel data, then encode it to BMP frame, and finally decode the BMP frame into a WinForms Bitmap. – Clemens Jul 24 '19 at 07:46
  • See e.g. [this question](https://stackoverflow.com/q/6782489/1136211) for how to directly create a Bitmap. – Clemens Jul 24 '19 at 07:47
  • You are apparently having a WinForms application. If you ever decide to switch to WPF, you would use a WriteableBitmap for this kind of problem. Instead of creating new bitmaps all the time, you would just repeatedly overwrite the WriteableBitmap's BackBuffer. – Clemens Jul 24 '19 at 07:51
  • Clemens, thank you for your opinion. But unfortunately, the basis of my program is Winform. You can't change it to WPF (The reference to Presentation.dll is to create a fast bitmap.) – Dongyeop Choi Jul 24 '19 at 08:03
  • You may find that creating a `Bitmap` with `PixelFormat.Format8bppIndexed` and writing to it using the [Bitmap.LockBits](https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.lockbits) method is faster, even without `unsafe` pointers. It lacks in the GrayScale formats department, though. `System.Windows.Media` has more choices and way better handling here. Unless you just need the `PixelFormats.Gray8` format. But this is not your problem. It looks like your timer may be making overlapping calls to the Bitmap creation procedure. It's just a supposition, looking at the code. – Jimi Jul 24 '19 at 08:49

0 Answers0