SavingImagesGame.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. //-----------------------------------------------------------------------------
  2. // SavingImagesGame.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.IO;
  9. using Microsoft.Xna.Framework;
  10. using Microsoft.Xna.Framework.GamerServices;
  11. using Microsoft.Xna.Framework.Graphics;
  12. using Microsoft.Xna.Framework.Input;
  13. using Microsoft.Xna.Framework.Input.Touch;
  14. using Microsoft.Xna.Framework.Media;
  15. namespace SavingEmbeddedImages
  16. {
  17. /// <summary>
  18. /// SavingEmbeddedImages shows two ways of transferring content from a game project to
  19. /// the Windows Phone 7 Media Library:
  20. ///
  21. /// 1. Loading an image texture from the game's content project, converting the
  22. /// image to a jpeg, and saving it to the media library.
  23. ///
  24. /// 2. Obtaining an image stream from the game project files and saving the stream
  25. /// to the media library
  26. /// </summary>
  27. public class SavingImagesGame : Microsoft.Xna.Framework.Game
  28. {
  29. GraphicsDeviceManager graphics;
  30. SpriteBatch spriteBatch;
  31. SpriteFont mainFont;
  32. SpriteFont detailFont;
  33. Texture2D backgroundImage;
  34. // This image will be loaded from the game project
  35. Texture2D gameProjectImage;
  36. // This image will be loaded from the content project
  37. Texture2D contentProjectImage;
  38. // Bounding rectangles are used for image display and hit-testing.
  39. // These coordinates were chosen to look nice, no other special reason.
  40. Rectangle gameProjectImageBounds = new Rectangle(20, 20, 200, 333);
  41. Rectangle contentProjectImageBounds = new Rectangle(260, 20, 200, 333);
  42. // Simple flag to ignore UI input when system dialogs are animating.
  43. bool imageSaveInProgress = false;
  44. /// <summary>
  45. /// Set up the game to run full screen and full resolution.
  46. /// </summary>
  47. public SavingImagesGame()
  48. {
  49. graphics = new GraphicsDeviceManager(this);
  50. graphics.PreferredBackBufferWidth = 480;
  51. graphics.PreferredBackBufferHeight = 800;
  52. graphics.IsFullScreen = true;
  53. Content.RootDirectory = "Content";
  54. // Frame rate is 30 fps by default for Windows Phone.
  55. TargetElapsedTime = TimeSpan.FromTicks(333333);
  56. }
  57. /// <summary>
  58. /// Perform pre-game initialization
  59. /// </summary>
  60. protected override void Initialize()
  61. {
  62. base.Initialize();
  63. // enable tap gestures only for this sample
  64. TouchPanel.EnabledGestures = GestureType.Tap;
  65. }
  66. /// <summary>
  67. /// Load UI content and fonts. Also create a drawable texture from both image types.
  68. /// </summary>
  69. protected override void LoadContent()
  70. {
  71. // Create a new SpriteBatch, which can be used to draw textures.
  72. spriteBatch = new SpriteBatch(GraphicsDevice);
  73. // Load the background image.
  74. backgroundImage = Content.Load<Texture2D>("GameBackground");
  75. // load the fonts
  76. mainFont = Content.Load<SpriteFont>("mainFont");
  77. detailFont = Content.Load<SpriteFont>("detailFont");
  78. // Load the embedded image from the game project using TitleContainer
  79. // and constructing a Texture2D from the resulting stream object.
  80. // Note that the image properties are set to "Copy if newer" in the
  81. // game project.
  82. using (Stream gameProjectImageStream = TitleContainer.OpenStream("GameProjectImage.jpg"))
  83. {
  84. gameProjectImage = Texture2D.FromStream(GraphicsDevice, gameProjectImageStream);
  85. }
  86. // Load the embedded image from the content project using the content loader.
  87. contentProjectImage = Content.Load<Texture2D>("ContentProjectImage");
  88. }
  89. /// <summary>
  90. /// Check for the back button to exit the app, and see if a touch occurred
  91. /// on one of the images.
  92. /// </summary>
  93. protected override void Update(GameTime gameTime)
  94. {
  95. // Allows the game to exit
  96. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  97. this.Exit();
  98. // check for touch input
  99. while (TouchPanel.IsGestureAvailable)
  100. {
  101. GestureSample gesture = TouchPanel.ReadGesture();
  102. // The text input dialog can allow input to occur between when it closes and when the
  103. // callback occurs, so the game guards against processing input in this state with a
  104. // simple flag.
  105. if (gesture.GestureType == GestureType.Tap && !imageSaveInProgress)
  106. {
  107. Point tapLocation = new Point((int)gesture.Position.X, (int)gesture.Position.Y);
  108. // An image touch triggersGuide.BeginShowKeyboardInput to receive
  109. // a filename. A hit-test determines which image was touched, and
  110. // the callback is different depending on the source of the image.
  111. if (gameProjectImageBounds.Contains(tapLocation))
  112. {
  113. imageSaveInProgress = true;
  114. Guide.BeginShowKeyboardInput(
  115. 0,
  116. "Save Picture",
  117. "Enter a filename for your image",
  118. "gameProjectImage",
  119. SaveGameProjectImageCallback,
  120. null);
  121. }
  122. if (contentProjectImageBounds.Contains(tapLocation))
  123. {
  124. imageSaveInProgress = true;
  125. Guide.BeginShowKeyboardInput(
  126. 0,
  127. "Save Picture",
  128. "Enter a filename for your image",
  129. "contentProjectImage",
  130. SaveContentProjectImageCallback,
  131. null);
  132. }
  133. }
  134. }
  135. base.Update(gameTime);
  136. }
  137. /// <summary>
  138. /// Render the UI.
  139. /// </summary>
  140. protected override void Draw(GameTime gameTime)
  141. {
  142. GraphicsDevice.Clear(Color.CornflowerBlue);
  143. spriteBatch.Begin();
  144. spriteBatch.Draw(backgroundImage, new Vector2(0, 0), Color.White);
  145. spriteBatch.Draw(gameProjectImage, gameProjectImageBounds, null, Color.White);
  146. spriteBatch.DrawString(
  147. detailFont,
  148. "game project image",
  149. new Vector2(gameProjectImageBounds.X, gameProjectImageBounds.Y + gameProjectImageBounds.Height),
  150. Color.White);
  151. spriteBatch.Draw(contentProjectImage, contentProjectImageBounds, null, Color.White);
  152. spriteBatch.DrawString(
  153. detailFont,
  154. "content project image",
  155. new Vector2(contentProjectImageBounds.X, contentProjectImageBounds.Y + contentProjectImageBounds.Height),
  156. Color.White);
  157. spriteBatch.DrawString(mainFont, "Tap an image to save it\nto your media library.", new Vector2(40,500), Color.White);
  158. spriteBatch.End();
  159. base.Draw(gameTime);
  160. }
  161. /// <summary>
  162. /// Utility function to save a stream to the media library. Media Library access won't
  163. /// work if the Zune desktop software is running.
  164. /// </summary>
  165. protected void SaveStreamToMediaLibrary(string filename, Stream stream)
  166. {
  167. MediaLibrary library = new MediaLibrary();
  168. string messageBoxTitle;
  169. string messageBoxContent;
  170. string[] buttons = { "OK" };
  171. MessageBoxIcon messageBoxIcon;
  172. try
  173. {
  174. library.SavePicture(filename, stream);
  175. messageBoxTitle = "Image saved.";
  176. messageBoxContent = filename + " successfully added to your Media Library.";
  177. messageBoxIcon = MessageBoxIcon.None;
  178. }
  179. catch (InvalidOperationException)
  180. {
  181. // The most likely reason for failure is that the Zune desktop software is running.
  182. // This prevents the phone from saving content to the device's media library.
  183. messageBoxTitle = "Unable to save image.";
  184. messageBoxContent = "The image could not be saved to the Media Library. One reason might be that the phone is tethered to a PC with the Zune software running.";
  185. // the phone doesn't display an icon, but specifying MessageBoxIcon.Error causes a warning sound effect to be played
  186. messageBoxIcon = MessageBoxIcon.Error;
  187. }
  188. IAsyncResult messageResult = Guide.BeginShowMessageBox(
  189. messageBoxTitle, messageBoxContent,
  190. buttons, 0, messageBoxIcon, null, null);
  191. Guide.EndShowMessageBox(messageResult);
  192. imageSaveInProgress = false;
  193. }
  194. /// <summary>
  195. /// Called when the user has picked a filename for the GameProject image.
  196. /// </summary>
  197. protected void SaveGameProjectImageCallback(IAsyncResult result)
  198. {
  199. string filename = Guide.EndShowKeyboardInput(result);
  200. if (!string.IsNullOrEmpty(filename))
  201. {
  202. // Both content images are loaded as textures for display, and could be
  203. // saved with Texture2D.SaveAsJpeg(), but if you need to go from
  204. // an image embedded in the .xap, an alternative approach is
  205. // to open a TitleContainer stream, and save it to the media library.
  206. using (Stream stream = TitleContainer.OpenStream("GameProjectImage.jpg"))
  207. {
  208. SaveStreamToMediaLibrary(filename, stream);
  209. }
  210. }
  211. else
  212. {
  213. imageSaveInProgress = false;
  214. }
  215. }
  216. /// <summary>
  217. /// Called when the user has picked a filename for the ContentProject image.
  218. /// </summary>
  219. protected void SaveContentProjectImageCallback(IAsyncResult result)
  220. {
  221. string filename = Guide.EndShowKeyboardInput(result);
  222. if (!string.IsNullOrEmpty(filename))
  223. {
  224. /// Write a Texture2D to a stream and then save the stream to the media library.
  225. // The media library expects a Jpeg image, so make sure it gets the input type it wants.
  226. using (MemoryStream stream = new MemoryStream())
  227. {
  228. contentProjectImage.SaveAsJpeg(stream, contentProjectImage.Width, contentProjectImage.Height);
  229. // Reset the stream position after writing to it.
  230. stream.Seek(0, 0);
  231. SaveStreamToMediaLibrary(filename, stream);
  232. }
  233. }
  234. else
  235. {
  236. imageSaveInProgress = false;
  237. }
  238. }
  239. }
  240. }