Save screenshots and texture2d under monogame 3.2

Source: Internet
Author: User

Note that because monogame 3.2 is used, the method is different from xNa 4.0.

The goal is to save the current graphicsdevice content as a texture2d file and output it to the file.

Screenshots have been taken for a long time under xNa. For example, xna4.0 saves the screen [1].

At the same time, for texture. saveaspng () (Under xNa), some people have long discovered the memory leakage problem and wrote their own solution: texture2d. saveaspng () Memory Leak [2].

However, on the Windows platform, monogame does not support texture2d. saveaspng () and texture2d. saveasjpeg (). Therefore, no matter what other people's memory leaks, the storage method must be implemented by themselves. (Please refer to the monogame Code. There are related foreign posts, but I forgot the address .)

In fact, I want to be lazy. After all, after saving it to texture2d, I have to write a piece of code to show it, disappear, and enter the original main loop, which is too troublesome. Besides, others' Code may not be feasible, save it as a file to see how it works. But there is something wrong with the storage ......

The link [2] has a saved implementation, but it is for xNa. When running on monogame, a color error occurs. That is to say, so far, at least no monogame developer has published a successful storage solution. (Of course, indie games like Fez won't be written online, right .)

The most noteworthy is the pixel format. GDI + is 0 xargb (but sometimes abgr, which was encountered during VB6), but what about monogame? (Monogame may not comply with xNa specifications here ?) I don't know. Surfaceformat. color was used several times before. In Microsoft documents, this is an RGB color with alpha channel, but the sequence is not specified (it should be argb later ). However, the monogame 3.2 windows (not windowsgl) template uses sharpdx, and DirectX defines a8r8g8b8 here. Saved directly. The color is incorrect. Compared to the same pixel, we found that 0xff3dab0d (correct) → 0xffd3abd0 (saved directly). Therefore, such processing still fails. The final successful result should be said to be accidental.

The error is not displayed here. I have attached it.Comments for recurring errorsIf you are interested, try it on your own.

The following is the code. Please add two references in advance:

1 using System.Drawing.Imaging;2 using System.Runtime.InteropServices;

Create an rendertarget2d object (inherited from texture2d) to save the screenshot content:

1 Public texture2d takescreenshot () 2 {3 int W, H; 4 W = graphicsdevice. presentationparameters. backbufferwidth; 5 H = graphicsdevice. presentationparameters. backbufferheight; 6 rendertarget2d screenshot; 7 // note that the format must be surfaceformat. bgra32, consistent with GDI +. The default surfaceformat. color will cause a color error. 8 screenshot = new rendertarget2d (graphicsdevice, W, H, false, surfaceformat. bgra32, depthformat. None); 9 graphicsdevice. setrendertarget (screenshot); 10 draw (_ lastupdatedgametime! = NULL? _ Lastupdatedgametime: New gametime (); 11 graphicsdevice. Present (); 12 graphicsdevice. setrendertarget (null); 13 return screenshot; 14}

Then the extension of texture2d (the Framework comes from the link [2]):

1 public static void save (this texture2d texture, imageformat, stream) 2 {3 var width = texture. width; 4 var Height = texture. height; 5 using (Bitmap bitmap = new Bitmap (width, height, pixelformat. format32bppargb) 6 {7 intptr safeptr; 8 bitmapdata; 9 system. drawing. rectangle rect = new system. drawing. rectangle (0, 0, width, height); 10 // use int [width * Height] instead of the byte [4 * width * Height] in the original text. otherwise, the image size is abnormal. 11 int [] texturedata = new int [width * Height]; 12 13 texture. getdata (texturedata); 14 bitmapdata = bitmap. lockbits (rect, imagelockmode. writeonly, pixelformat. format32bppargb); 15 safeptr = bitmapdata. scan0; 16 marshal. copy (texturedata, 0, safeptr, texturedata. length); 17 bitmap. unlockbits (bitmapdata); 18 bitmap. save (stream, imageformat); 19 20 texturedata = NULL; 21} 22 GC. collect (); 23}

Finally, call:

1 void mainbutton4_mouseclick (Object sender, mouseeventargs E) 2 {3 var screenshot = rootcontrolcontainer. takescreenshot (); 4 If (screenshot! = NULL) 5 {6 // system. drawing. bitmap. the file name of the SAVE () method must be an absolute path 7 // and it is difficult to obtain an absolute path under monogame. Therefore, to save the file to a relative path, use system. io. filestream 8 using (var fs = new system. io. filestream (@ "screenshot.png", system. io. filemode. openorcreate) 9 {10 screenshot. save (system. drawing. imaging. imageformat. PNG, FS); 11} 12 screenshot. dispose (); 13} 14}

Save screenshots and texture2d under monogame 3.2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.