PageRenderTime 55ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/Wrapper/FreeImage.NET/cs/Samples/Sample 11 - Using the FreeImageBitmap class/MainForm.cs

https://gitlab.com/seranth/FreeImage
C# | 412 lines | 326 code | 28 blank | 58 comment | 62 complexity | 348fe20f9ba284248d0e27d93b3f1402 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Windows.Forms;
  6. using FreeImageAPI;
  7. using FreeImageAPI.Metadata;
  8. using FreeImageAPI.Plugins;
  9. namespace Sample11
  10. {
  11. public partial class MainForm : Form
  12. {
  13. public MainForm()
  14. {
  15. InitializeComponent();
  16. }
  17. [STAThread]
  18. static void Main()
  19. {
  20. // Capture messages generated by FreeImage
  21. FreeImageEngine.Message += new OutputMessageFunction(FreeImageEngine_Message);
  22. Application.EnableVisualStyles();
  23. Application.SetCompatibleTextRenderingDefault(false);
  24. Application.Run(new MainForm());
  25. }
  26. static void FreeImageEngine_Message(FREE_IMAGE_FORMAT fif, string message)
  27. {
  28. // Display the message
  29. // FreeImage continues code executing when all
  30. // addes subscribers of 'Message' finished returned.
  31. MessageBox.Show(message, "FreeImage-Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
  32. }
  33. // The FreeImageBitmap this sample will work with.
  34. FreeImageBitmap bitmap = null;
  35. // Replaces the current bitmap with the given one.
  36. private void ReplaceBitmap(FreeImageBitmap newBitmap)
  37. {
  38. // Checks whether the bitmap is usable
  39. if (newBitmap == null || newBitmap.IsDisposed)
  40. {
  41. MessageBox.Show(
  42. "Unexpected error.",
  43. "Error",
  44. MessageBoxButtons.OK,
  45. MessageBoxIcon.Error);
  46. }
  47. // Check whether the image type of the new bitmap is 'FIT_BITMAP'.
  48. // If not convert to 'FIT_BITMAP'.
  49. if (newBitmap.ImageType != FREE_IMAGE_TYPE.FIT_BITMAP)
  50. {
  51. if (!newBitmap.ConvertType(FREE_IMAGE_TYPE.FIT_BITMAP, true))
  52. {
  53. MessageBox.Show(
  54. "Error converting bitmap to standard type.",
  55. "Error",
  56. MessageBoxButtons.OK,
  57. MessageBoxIcon.Error);
  58. return;
  59. }
  60. }
  61. // Dispose the old bitmap only in case it exists and
  62. // the old instance is another than the new one.
  63. if ((bitmap != null) && !object.ReferenceEquals(bitmap, newBitmap))
  64. {
  65. bitmap.Dispose();
  66. }
  67. // Dispose the picturebox's bitmap in case it exists.
  68. if (pictureBox.Image != null)
  69. {
  70. pictureBox.Image.Dispose();
  71. }
  72. // Set the new bitmap.
  73. pictureBox.Image = (Bitmap)(bitmap = newBitmap);
  74. // Update gui.
  75. UpdateBitmapInformations();
  76. UpdateFrameSelection();
  77. }
  78. // Get bitmap properties and display them in the gui.
  79. private void UpdateBitmapInformations()
  80. {
  81. if (Bitmap)
  82. {
  83. // Get width
  84. lWidth.Text = String.Format("Width: {0}", bitmap.Width);
  85. // Get Height
  86. lHeight.Text = String.Format("Height: {0}", bitmap.Height);
  87. // Get color depth
  88. lBpp.Text = String.Format("Bpp: {0}", bitmap.ColorDepth);
  89. // Get number of metadata
  90. ImageMetadata mData = bitmap.Metadata;
  91. mData.HideEmptyModels = true;
  92. int mCnt = 0;
  93. foreach (MetadataModel model in mData.List)
  94. {
  95. mCnt += model.Count;
  96. }
  97. lMetadataCount.Text = String.Format("Metadata: {0}", mCnt);
  98. // Get image comment
  99. lComment.Text = String.Format("Image-comment: {0}", bitmap.Comment != null ? bitmap.Comment : String.Empty);
  100. // Get the number of real colors in the image
  101. lColors.Text = String.Format("Colors: {0}", bitmap.UniqueColors);
  102. }
  103. else
  104. {
  105. // Reset all values
  106. lWidth.Text = String.Format("Width: {0}", 0);
  107. lHeight.Text = String.Format("Height: {0}", 0);
  108. lBpp.Text = String.Format("Bpp: {0}", 0);
  109. lMetadataCount.Text = String.Format("Metadata: {0}", 0);
  110. lComment.Text = String.Format("Image-comment: {0}", String.Empty);
  111. lColors.Text = String.Format("Colors: {0}", 0);
  112. }
  113. }
  114. // Update combobox for frame selection.
  115. private void UpdateFrameSelection()
  116. {
  117. cbSelectFrame.Items.Clear();
  118. if (Bitmap)
  119. {
  120. // Get number of frames in the bitmap
  121. if (bitmap.FrameCount > 1)
  122. {
  123. // Add an entry for each frame to the combobox
  124. for (int i = 0; i < bitmap.FrameCount; i++)
  125. {
  126. cbSelectFrame.Items.Add(String.Format("Frame {0}", i + 1));
  127. }
  128. }
  129. }
  130. }
  131. // Returns true in case the variable 'bitmap'
  132. // is set and not disposed.
  133. private bool Bitmap
  134. {
  135. get { return ((bitmap != null) && (!bitmap.IsDisposed)); }
  136. }
  137. private void bLoadImage_Click(object sender, EventArgs e)
  138. {
  139. if (ofd.ShowDialog() == DialogResult.OK)
  140. {
  141. try
  142. {
  143. // Load the file using autodetection
  144. FreeImageBitmap fib = new FreeImageBitmap(ofd.FileName);
  145. // Rescale the image so that it fits the picturebox
  146. // Get the plugin that was used to load the bitmap
  147. FreeImagePlugin plug = PluginRepository.Plugin(fib.ImageFormat);
  148. lImageFormat.Text = String.Format("Image-format: {0}", plug.Format);
  149. // Replace the existing bitmap with the new one
  150. ReplaceBitmap(fib);
  151. }
  152. catch
  153. {
  154. }
  155. }
  156. }
  157. private void bSaveImage_Click(object sender, EventArgs e)
  158. {
  159. if (pictureBox.Image != null)
  160. {
  161. try
  162. {
  163. if (sfd.ShowDialog() == DialogResult.OK)
  164. {
  165. // Save the bitmap using autodetection
  166. using (FreeImageBitmap temp = new FreeImageBitmap(pictureBox.Image))
  167. {
  168. temp.Save(sfd.FileName);
  169. }
  170. }
  171. }
  172. catch
  173. {
  174. }
  175. }
  176. }
  177. private void bRotate_Click(object sender, EventArgs e)
  178. {
  179. if (Bitmap)
  180. {
  181. // Create a temporary rescaled bitmap
  182. using (FreeImageBitmap temp = bitmap.GetScaledInstance(
  183. pictureBox.DisplayRectangle.Width, pictureBox.DisplayRectangle.Height,
  184. FREE_IMAGE_FILTER.FILTER_CATMULLROM))
  185. {
  186. if (temp != null)
  187. {
  188. // Rotate the bitmap
  189. temp.Rotate((double)vRotate.Value);
  190. if (pictureBox.Image != null)
  191. {
  192. pictureBox.Image.Dispose();
  193. }
  194. // Display the result
  195. pictureBox.Image = (Bitmap)temp;
  196. }
  197. }
  198. }
  199. }
  200. private void bGreyscale_Click(object sender, EventArgs e)
  201. {
  202. if (Bitmap)
  203. {
  204. // Convert the bitmap to 8bpp and greyscale
  205. ReplaceBitmap(bitmap.GetColorConvertedInstance(
  206. FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP |
  207. FREE_IMAGE_COLOR_DEPTH.FICD_FORCE_GREYSCALE));
  208. }
  209. }
  210. private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
  211. {
  212. ComboBox cb = sender as ComboBox;
  213. if ((cb != null) && (cb.Items.Count > 0))
  214. {
  215. if (Bitmap)
  216. {
  217. try
  218. {
  219. // Switch the selected frame
  220. bitmap.SelectActiveFrame(cb.SelectedIndex);
  221. ReplaceBitmap(bitmap);
  222. }
  223. catch (ArgumentOutOfRangeException)
  224. {
  225. MessageBox.Show("Error changing frame.", "Error");
  226. }
  227. }
  228. }
  229. }
  230. private void bAdjustGamma_Click(object sender, EventArgs e)
  231. {
  232. if (Bitmap)
  233. {
  234. // Adjust the gamma value
  235. bitmap.AdjustGamma((double)vGamma.Value);
  236. ReplaceBitmap(bitmap);
  237. }
  238. }
  239. private void bRedChannelOnly_Click(object sender, EventArgs e)
  240. {
  241. // Mask out green and blue
  242. SetColorChannels(0xFF, 0x00, 0x00);
  243. }
  244. private void bGreenChannel_Click(object sender, EventArgs e)
  245. {
  246. // Mask out red and blue
  247. SetColorChannels(0x00, 0xFF, 0x00);
  248. }
  249. private void bBlueChannel_Click(object sender, EventArgs e)
  250. {
  251. // Mask out red and green
  252. SetColorChannels(0x00, 0x00, 0xFF);
  253. }
  254. private void bAllChannels_Click(object sender, EventArgs e)
  255. {
  256. if (Bitmap)
  257. {
  258. // Restore the bitmap using the original
  259. ReplaceBitmap(bitmap);
  260. }
  261. }
  262. private void SetColorChannels(int redmask, int greenmask, int bluemask)
  263. {
  264. if (Bitmap)
  265. {
  266. // Create a temporary clone.
  267. using (FreeImageBitmap bitmap = (FreeImageBitmap)this.bitmap.Clone())
  268. {
  269. if (bitmap != null)
  270. {
  271. // Check whether the bitmap has a palette
  272. if (bitmap.HasPalette)
  273. {
  274. // Use the Palette class to handle the bitmap's
  275. // palette. A palette always consist of RGBQUADs.
  276. Palette palette = bitmap.Palette;
  277. // Apply the new values for all three color components.
  278. for (int i = 0; i < palette.Length; i++)
  279. {
  280. RGBQUAD rgbq = palette[i];
  281. rgbq.rgbRed = (byte)(rgbq.rgbRed & redmask);
  282. rgbq.rgbGreen = (byte)(rgbq.rgbGreen & greenmask);
  283. rgbq.rgbBlue = (byte)(rgbq.rgbBlue & bluemask);
  284. palette[i] = rgbq;
  285. }
  286. }
  287. // In case the bitmap has no palette it must have a color depth
  288. // of 16, 24 or 32. Each color depth needs a different wrapping
  289. // structure for the bitmaps data. These structures can be accessed
  290. // by using the foreach clause.
  291. else if (bitmap.ColorDepth == 16)
  292. {
  293. // Iterate over each scanline
  294. // For 16bpp use either Scanline<FI16RGB555> or Scanline<FI16RGB565>
  295. if (bitmap.IsRGB555)
  296. {
  297. foreach (Scanline<FI16RGB555> scanline in bitmap)
  298. {
  299. for (int x = 0; x < scanline.Length; x++)
  300. {
  301. FI16RGB555 pixel = scanline[x];
  302. pixel.Red = (byte)(pixel.Red & redmask);
  303. pixel.Green = (byte)(pixel.Green & greenmask);
  304. pixel.Blue = (byte)(pixel.Blue & bluemask);
  305. scanline[x] = pixel;
  306. }
  307. }
  308. }
  309. else if (bitmap.IsRGB565)
  310. {
  311. foreach (Scanline<FI16RGB565> scanline in bitmap)
  312. {
  313. for (int x = 0; x < scanline.Length; x++)
  314. {
  315. FI16RGB565 pixel = scanline[x];
  316. pixel.Red = (byte)(pixel.Red & redmask);
  317. pixel.Green = (byte)(pixel.Green & greenmask);
  318. pixel.Blue = (byte)(pixel.Blue & bluemask);
  319. scanline[x] = pixel;
  320. }
  321. }
  322. }
  323. }
  324. else if (bitmap.ColorDepth == 24)
  325. {
  326. // Iterate over each scanline
  327. // For 24bpp Scanline<RGBTRIPLE> must be used
  328. foreach (Scanline<RGBTRIPLE> scanline in bitmap)
  329. {
  330. for (int x = 0; x < scanline.Length; x++)
  331. {
  332. RGBTRIPLE pixel = scanline[x];
  333. pixel.rgbtRed = (byte)(pixel.rgbtRed & redmask);
  334. pixel.rgbtGreen = (byte)(pixel.rgbtGreen & greenmask);
  335. pixel.rgbtBlue = (byte)(pixel.rgbtBlue & bluemask);
  336. scanline[x] = pixel;
  337. }
  338. }
  339. }
  340. else if (bitmap.ColorDepth == 32)
  341. {
  342. // Iterate over each scanline
  343. // For 32bpp Scanline<RGBQUAD> must be used
  344. foreach (Scanline<RGBQUAD> scanline in bitmap)
  345. {
  346. for (int x = 0; x < scanline.Length; x++)
  347. {
  348. RGBQUAD pixel = scanline[x];
  349. pixel.rgbRed = (byte)(pixel.rgbRed & redmask);
  350. pixel.rgbGreen = (byte)(pixel.rgbGreen & greenmask);
  351. pixel.rgbBlue = (byte)(pixel.rgbBlue & bluemask);
  352. scanline[x] = pixel;
  353. }
  354. }
  355. }
  356. // Dispose only the picturebox's bitmap
  357. if (pictureBox.Image != null)
  358. {
  359. pictureBox.Image.Dispose();
  360. }
  361. pictureBox.Image = (Bitmap)bitmap;
  362. }
  363. }
  364. }
  365. }
  366. private void vRotate_Scroll(object sender, EventArgs e)
  367. {
  368. TrackBar bar = sender as TrackBar;
  369. if (bar != null)
  370. {
  371. lRotate.Text = bar.Value.ToString();
  372. }
  373. }
  374. private void nShowMetadata_Click(object sender, EventArgs e)
  375. {
  376. if (Bitmap)
  377. {
  378. MetaDataFrame mFrame = new MetaDataFrame();
  379. mFrame.Tag = bitmap.Metadata;
  380. mFrame.ShowDialog(this);
  381. }
  382. }
  383. }
  384. }