0

I have a pretty simple piece of code that takes a ScreenShot and then convert it to bytes to make screen sharing. It works well when using it on Unity but as soon as I try on a built .exe. I have a NullPointerException even though none of the variables are null. Can you help me ?

I've tried a lot of different pieces of code to convert the bitmap in bytes but all give the same error. See the two version I've tried in the code below.

First the screenshot function

public static Bitmap TakeScreenshot()
{
     Rectangle totalSize = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;

     Bitmap screenShotBMP = new Bitmap(totalSize.Width, totalSize.Height, PixelFormat.Format32bppArgb);

    System.Drawing.Graphics screenShotGraphics = System.Drawing.Graphics.FromImage(screenShotBMP);

    screenShotGraphics.CopyFromScreen(totalSize.X, totalSize.Y, 0, 0, totalSize.Size,CopyPixelOperation.SourceCopy);

    screenShotGraphics.Dispose();

    return 
}

Then my simplest code creating the stream

Bitmap bitmap = TakeScreenshot();
ImageConverter converter = new ImageConverter();
bytes = converter.ConvertTo(bitmap, typeof(byte[])) as byte[];
bitmap.Dispose();

And I've tried something like this because I wanted to change the quality

 using (Bitmap bitmap = TakeScreenshot())
{
    using (MemoryStream stream = new MemoryStream())
    {
        ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
        // Create an Encoder object based on the GUID  
        // for the Quality parameter category.  
        System.Drawing.Imaging.Encoder myEncoder =                                    System.Drawing.Imaging.Encoder.Quality;

        // Create an EncoderParameters object.  
        // An EncoderParameters object has an array of EncoderParameter  
        // objects. In this case, there is only one  
        // EncoderParameter object in the array.  
        EncoderParameters myEncoderParameters = new EncoderParameters(1);                                
        EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, screenCaptureQuality);                                

        myEncoderParameters.Param[0] = myEncoderParameter;                               
        bitmap.Save(stream,jpgEncoder,myEncoderParameters);
        bytes = stream.ToArray();
     }                            
}

It works well on Unity but not when built. I feel like it's a dll problem but I don't really know what I should try to fix.

Here is the error I get.

Uploading Crash Report NullReferenceException: Object reference not set to an instance of an object
  at System.Drawing.ComIStreamMarshaler+ManagedToNativeWrapper..cctor () [0x00049] in <7649986197334871a851fbd08bc03690>:0 
Rethrow as TypeInitializationException: The type initializer for 'ManagedToNativeWrapper' threw an exception.
  at System.Drawing.ComIStreamMarshaler.MarshalManagedToNative (System.Object managedObj) [0x00000] in <7649986197334871a851fbd08bc03690>:0 
  at (wrapper managed-to-native) System.Drawing.GDIPlus.GdipSaveImageToStream(System.Runtime.InteropServices.HandleRef,System.Runtime.InteropServices.ComTypes.IStream,System.Guid&,System.Runtime.InteropServices.HandleRef)
  at System.Drawing.Image.Save (System.IO.Stream stream, System.Drawing.Imaging.ImageCodecInfo encoder, System.Drawing.Imaging.EncoderParameters encoderParams) [0x0007e] in <7649986197334871a851fbd08bc03690>:0 
  at System.Drawing.Image.Save (System.IO.Stream stream, System.Drawing.Imaging.ImageFormat format) [0x00029] in <7649986197334871a851fbd08bc03690>:0 
  at (wrapper remoting-invoke-with-check) System.Drawing.Image.Save(System.IO.Stream,System.Drawing.Imaging.ImageFormat)
  at System.Drawing.ImageConverter.ConvertTo (System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, System.Object value, System.Type destinationType) [0x00055] in <7649986197334871a851fbd08bc03690>:0 
  at System.ComponentModel.TypeConverter.ConvertTo (System.Object value, System.Type destinationType) [0x00000] in <d465e2b2e5054d2787d6364114c43446>:0 
  at DuneGestion.Messenger.CallController+<CallInProgress>d__21.MoveNext () [0x00184] in D:\UnityProject\DuneMessenger\Assets\Scripts\DarkRiftServer\CallController.cs:154 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00027] in <4d22bb06641f46818a5212b4c17a7772>:0 

Thanks and regards

  • 1
    Have you tried to use Unity's [ScreenCapture](https://docs.unity3d.com/ScriptReference/ScreenCapture.html)? – aalmigthy Sep 12 '19 at 14:38
  • What is line 154 of your CallController.cs script? – Erik Overflow Sep 12 '19 at 14:47
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Ruzihm Sep 12 '19 at 15:07
  • `System.Windows.Forms...` Unity is not a Windows Forms application, this package is unlikely to be present when you build. – Draco18s no longer trusts SE Sep 12 '19 at 16:13
  • Hi and thanks for your answers. In order :@aalmigthy ScreenCapture capture only the app if I recall correctly.I want the entire screen cause you can share something outside of the app. Line 154 is this line : @ErikOverflow `bitmap.Save(stream,jpgEncoder,myEncoderParameters);` @Ruzihm I have 10 years experience in programming and I know what's a NPE. Waht's weird here is none of the variables are null but I still have a NPE. Never seens that before. Lastly @Draco18s, I've added the reference and it's in my plugins folder in Unity. It should work. Never add any issues using this. – Alex .R Sep 13 '19 at 09:18
  • UP ! Please... :) – Alex .R Sep 17 '19 at 13:20

0 Answers0