blob: 0cb99730c3405a776299d38c258ad5bc28fa0896 [file] [log] [blame]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using FreeImageAPI;
using FreeImageAPI.Metadata;
using FreeImageAPI.Plugins;
namespace Sample11
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
[STAThread]
static void Main()
{
// Capture messages generated by FreeImage
FreeImageEngine.Message += new OutputMessageFunction(FreeImageEngine_Message);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
static void FreeImageEngine_Message(FREE_IMAGE_FORMAT fif, string message)
{
// Display the message
// FreeImage continues code executing when all
// addes subscribers of 'Message' finished returned.
MessageBox.Show(message, "FreeImage-Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// The FreeImageBitmap this sample will work with.
FreeImageBitmap bitmap = null;
// Replaces the current bitmap with the given one.
private void ReplaceBitmap(FreeImageBitmap newBitmap)
{
// Checks whether the bitmap is usable
if (newBitmap == null || newBitmap.IsDisposed)
{
MessageBox.Show(
"Unexpected error.",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
// Check whether the image type of the new bitmap is 'FIT_BITMAP'.
// If not convert to 'FIT_BITMAP'.
if (newBitmap.ImageType != FREE_IMAGE_TYPE.FIT_BITMAP)
{
if (!newBitmap.ConvertType(FREE_IMAGE_TYPE.FIT_BITMAP, true))
{
MessageBox.Show(
"Error converting bitmap to standard type.",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
}
// Dispose the old bitmap only in case it exists and
// the old instance is another than the new one.
if ((bitmap != null) && !object.ReferenceEquals(bitmap, newBitmap))
{
bitmap.Dispose();
}
// Dispose the picturebox's bitmap in case it exists.
if (pictureBox.Image != null)
{
pictureBox.Image.Dispose();
}
// Set the new bitmap.
pictureBox.Image = (Bitmap)(bitmap = newBitmap);
// Update gui.
UpdateBitmapInformations();
UpdateFrameSelection();
}
// Get bitmap properties and display them in the gui.
private void UpdateBitmapInformations()
{
if (Bitmap)
{
// Get width
lWidth.Text = String.Format("Width: {0}", bitmap.Width);
// Get Height
lHeight.Text = String.Format("Height: {0}", bitmap.Height);
// Get color depth
lBpp.Text = String.Format("Bpp: {0}", bitmap.ColorDepth);
// Get number of metadata
ImageMetadata mData = bitmap.Metadata;
mData.HideEmptyModels = true;
int mCnt = 0;
foreach (MetadataModel model in mData.List)
{
mCnt += model.Count;
}
lMetadataCount.Text = String.Format("Metadata: {0}", mCnt);
// Get image comment
lComment.Text = String.Format("Image-comment: {0}", bitmap.Comment != null ? bitmap.Comment : String.Empty);
// Get the number of real colors in the image
lColors.Text = String.Format("Colors: {0}", bitmap.UniqueColors);
}
else
{
// Reset all values
lWidth.Text = String.Format("Width: {0}", 0);
lHeight.Text = String.Format("Height: {0}", 0);
lBpp.Text = String.Format("Bpp: {0}", 0);
lMetadataCount.Text = String.Format("Metadata: {0}", 0);
lComment.Text = String.Format("Image-comment: {0}", String.Empty);
lColors.Text = String.Format("Colors: {0}", 0);
}
}
// Update combobox for frame selection.
private void UpdateFrameSelection()
{
cbSelectFrame.Items.Clear();
if (Bitmap)
{
// Get number of frames in the bitmap
if (bitmap.FrameCount > 1)
{
// Add an entry for each frame to the combobox
for (int i = 0; i < bitmap.FrameCount; i++)
{
cbSelectFrame.Items.Add(String.Format("Frame {0}", i + 1));
}
}
}
}
// Returns true in case the variable 'bitmap'
// is set and not disposed.
private bool Bitmap
{
get { return ((bitmap != null) && (!bitmap.IsDisposed)); }
}
private void bLoadImage_Click(object sender, EventArgs e)
{
if (ofd.ShowDialog() == DialogResult.OK)
{
try
{
// Load the file using autodetection
FreeImageBitmap fib = new FreeImageBitmap(ofd.FileName);
// Rescale the image so that it fits the picturebox
// Get the plugin that was used to load the bitmap
FreeImagePlugin plug = PluginRepository.Plugin(fib.ImageFormat);
lImageFormat.Text = String.Format("Image-format: {0}", plug.Format);
// Replace the existing bitmap with the new one
ReplaceBitmap(fib);
}
catch
{
}
}
}
private void bSaveImage_Click(object sender, EventArgs e)
{
if (pictureBox.Image != null)
{
try
{
if (sfd.ShowDialog() == DialogResult.OK)
{
// Save the bitmap using autodetection
using (FreeImageBitmap temp = new FreeImageBitmap(pictureBox.Image))
{
temp.Save(sfd.FileName);
}
}
}
catch
{
}
}
}
private void bRotate_Click(object sender, EventArgs e)
{
if (Bitmap)
{
// Create a temporary rescaled bitmap
using (FreeImageBitmap temp = bitmap.GetScaledInstance(
pictureBox.DisplayRectangle.Width, pictureBox.DisplayRectangle.Height,
FREE_IMAGE_FILTER.FILTER_CATMULLROM))
{
if (temp != null)
{
// Rotate the bitmap
temp.Rotate((double)vRotate.Value);
if (pictureBox.Image != null)
{
pictureBox.Image.Dispose();
}
// Display the result
pictureBox.Image = (Bitmap)temp;
}
}
}
}
private void bGreyscale_Click(object sender, EventArgs e)
{
if (Bitmap)
{
// Convert the bitmap to 8bpp and greyscale
ReplaceBitmap(bitmap.GetColorConvertedInstance(
FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP |
FREE_IMAGE_COLOR_DEPTH.FICD_FORCE_GREYSCALE));
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cb = sender as ComboBox;
if ((cb != null) && (cb.Items.Count > 0))
{
if (Bitmap)
{
try
{
// Switch the selected frame
bitmap.SelectActiveFrame(cb.SelectedIndex);
ReplaceBitmap(bitmap);
}
catch (ArgumentOutOfRangeException)
{
MessageBox.Show("Error changing frame.", "Error");
}
}
}
}
private void bAdjustGamma_Click(object sender, EventArgs e)
{
if (Bitmap)
{
// Adjust the gamma value
bitmap.AdjustGamma((double)vGamma.Value);
ReplaceBitmap(bitmap);
}
}
private void bRedChannelOnly_Click(object sender, EventArgs e)
{
// Mask out green and blue
SetColorChannels(0xFF, 0x00, 0x00);
}
private void bGreenChannel_Click(object sender, EventArgs e)
{
// Mask out red and blue
SetColorChannels(0x00, 0xFF, 0x00);
}
private void bBlueChannel_Click(object sender, EventArgs e)
{
// Mask out red and green
SetColorChannels(0x00, 0x00, 0xFF);
}
private void bAllChannels_Click(object sender, EventArgs e)
{
if (Bitmap)
{
// Restore the bitmap using the original
ReplaceBitmap(bitmap);
}
}
private void SetColorChannels(int redmask, int greenmask, int bluemask)
{
if (Bitmap)
{
// Create a temporary clone.
using (FreeImageBitmap bitmap = (FreeImageBitmap)this.bitmap.Clone())
{
if (bitmap != null)
{
// Check whether the bitmap has a palette
if (bitmap.HasPalette)
{
// Use the Palette class to handle the bitmap's
// palette. A palette always consist of RGBQUADs.
Palette palette = bitmap.Palette;
// Apply the new values for all three color components.
for (int i = 0; i < palette.Length; i++)
{
RGBQUAD rgbq = palette[i];
rgbq.rgbRed = (byte)(rgbq.rgbRed & redmask);
rgbq.rgbGreen = (byte)(rgbq.rgbGreen & greenmask);
rgbq.rgbBlue = (byte)(rgbq.rgbBlue & bluemask);
palette[i] = rgbq;
}
}
// In case the bitmap has no palette it must have a color depth
// of 16, 24 or 32. Each color depth needs a different wrapping
// structure for the bitmaps data. These structures can be accessed
// by using the foreach clause.
else if (bitmap.ColorDepth == 16)
{
// Iterate over each scanline
// For 16bpp use either Scanline<FI16RGB555> or Scanline<FI16RGB565>
if (bitmap.IsRGB555)
{
foreach (Scanline<FI16RGB555> scanline in bitmap)
{
for (int x = 0; x < scanline.Length; x++)
{
FI16RGB555 pixel = scanline[x];
pixel.Red = (byte)(pixel.Red & redmask);
pixel.Green = (byte)(pixel.Green & greenmask);
pixel.Blue = (byte)(pixel.Blue & bluemask);
scanline[x] = pixel;
}
}
}
else if (bitmap.IsRGB565)
{
foreach (Scanline<FI16RGB565> scanline in bitmap)
{
for (int x = 0; x < scanline.Length; x++)
{
FI16RGB565 pixel = scanline[x];
pixel.Red = (byte)(pixel.Red & redmask);
pixel.Green = (byte)(pixel.Green & greenmask);
pixel.Blue = (byte)(pixel.Blue & bluemask);
scanline[x] = pixel;
}
}
}
}
else if (bitmap.ColorDepth == 24)
{
// Iterate over each scanline
// For 24bpp Scanline<RGBTRIPLE> must be used
foreach (Scanline<RGBTRIPLE> scanline in bitmap)
{
for (int x = 0; x < scanline.Length; x++)
{
RGBTRIPLE pixel = scanline[x];
pixel.rgbtRed = (byte)(pixel.rgbtRed & redmask);
pixel.rgbtGreen = (byte)(pixel.rgbtGreen & greenmask);
pixel.rgbtBlue = (byte)(pixel.rgbtBlue & bluemask);
scanline[x] = pixel;
}
}
}
else if (bitmap.ColorDepth == 32)
{
// Iterate over each scanline
// For 32bpp Scanline<RGBQUAD> must be used
foreach (Scanline<RGBQUAD> scanline in bitmap)
{
for (int x = 0; x < scanline.Length; x++)
{
RGBQUAD pixel = scanline[x];
pixel.rgbRed = (byte)(pixel.rgbRed & redmask);
pixel.rgbGreen = (byte)(pixel.rgbGreen & greenmask);
pixel.rgbBlue = (byte)(pixel.rgbBlue & bluemask);
scanline[x] = pixel;
}
}
}
// Dispose only the picturebox's bitmap
if (pictureBox.Image != null)
{
pictureBox.Image.Dispose();
}
pictureBox.Image = (Bitmap)bitmap;
}
}
}
}
private void vRotate_Scroll(object sender, EventArgs e)
{
TrackBar bar = sender as TrackBar;
if (bar != null)
{
lRotate.Text = bar.Value.ToString();
}
}
private void nShowMetadata_Click(object sender, EventArgs e)
{
if (Bitmap)
{
MetaDataFrame mFrame = new MetaDataFrame();
mFrame.Tag = bitmap.Metadata;
mFrame.ShowDialog(this);
}
}
}
}