TIFF compression - c#

I am trying to compress some TIFF files. These are in a certain map structure, and so they should stay. With the code bellow, I am able to convert every first file (named 1.tiff) in every subdirectory, but it gives me a System.ArgumentException when there are more than one file in a subdirectory, or if the name of the file is not 1.tiff.
using RasterEdge.Imaging.Basic;
using RasterEdge.XDoc.TIFF;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace LZWCompression
{
class Program
{
static int temp = 0;
static void Main(string[] args)
{
string root = #"C:x\y\";
string path = "z";
Console.WriteLine(Directory.Exists(root + path));
if (Directory.Exists(root + path))
{
// This path is a directory
ProcessDirectory(root + path, root);
Console.WriteLine(root + path);
}
Console.WriteLine("DONE");
Console.ReadKey();
}
// Process all files in the directory passed in, recurse on any directories
// that are found, and process the files they contain.
public static void ProcessDirectory(string targetDirectory, string targetPath)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries)
{
Console.WriteLine(fileName);
ProcessFile(fileName, targetPath);
}
// Recurse into subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory, targetPath);
}
public static void ProcessFile(string path, string root)
{
string filename = "";
string location = "";
temp++;
List<Bitmap> images = new List<Bitmap>();
int posFilename = path.LastIndexOf("\\") + 1;
int posRoot = root.Length;
filename = path.Substring(posFilename, path.Length - posFilename);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(800, 1000);
Graphics g = Graphics.FromImage(bitmap);
posFilename = posFilename - (posRoot + 1);
location = path.Substring(posRoot, posFilename);
Bitmap myBitmap;
myBitmap = new Bitmap(filename);
ImageCodecInfo myImageCodecInfo;
myImageCodecInfo = GetEncoderInfo(filename);
System.Drawing.Imaging.Encoder myEncoder;
myEncoder = System.Drawing.Imaging.Encoder.Compression;
EncoderParameters myEncoderParameters;
myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter;
myEncoderParameter = new EncoderParameter(myEncoder, (long)EncoderValue.CompressionLZW);
myEncoderParameters.Param[0] = myEncoderParameter;
myBitmap.Save(path, ImageFormat.Tiff);
Console.WriteLine("myBitmap: " + myBitmap.ToString());
Bitmap bm = (Bitmap)Bitmap.FromFile(path);
bm = ChangeColor(bm);
images.Add(bm);
TIFFDocument doc = new TIFFDocument(images.ToArray(), ImageCompress.LZW);
if (null == doc)
throw new Exception("Fail to construct TIFF Document");
doc.Save(path);
}
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
public static Bitmap ChangeColor(Bitmap original)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
//get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
//create the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
ImageAttributes attributes = new ImageAttributes();
g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
//dispose the Graphics object
g.Dispose();
return newBitmap;
}
}
}

Related

How to convert TIF to Black-and-White Monochrome TIF

I would like to use Magick.NET
https://magick.codeplex.com/wikipage?title=Convert%20image&referringTitle=Documentation
in order to convert TIF to Black-and-White Monochrome TIF but manual does not explain it well.
I have tried this code but I am not sure of this approach is a correct one.
using (MagickImage image = new MagickImage("input.tif"))
{
image.CompressionMethod = CompressionMethod.Group4;
image.Write("output.tif");
}
Help needed. Thank you!
I found .NET code to do the same thing without any issues.
http://www.codeproject.com/Articles/15186/Bitonal-TIFF-Image-Converter-for-NET
private void convert_Click(object sender, EventArgs e)
{
// Load a bitmap from disk
Bitmap originalBitmap = new Bitmap(#"..\..\Bitonal-In.tif");
// Display image
originalImage.Image = originalBitmap;
// Convert bitmap to RGB format for drawing
Bitmap rgbBitmap = Converter.ConvertToRGB(originalBitmap);
// Convert image to bitonal for saving to file
Bitmap bitonalBitmap = Converter.ConvertToBitonal(rgbBitmap);
// Display converted image
convertedImage.Image = bitonalBitmap;
// Get an ImageCodecInfo object that represents the TIFF codec.
ImageCodecInfo imageCodecInfo = GetEncoderInfo("image/tiff");
System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.Compression;
EncoderParameters encoderParameters = new EncoderParameters(1);
// Save the bitmap as a TIFF file with group IV compression.
EncoderParameter encoderParameter = new EncoderParameter(encoder, (long)EncoderValue.CompressionCCITT4);
encoderParameters.Param[0] = encoderParameter;
bitonalBitmap.Save(#"..\..\Bitonal-Out.tif", imageCodecInfo, encoderParameters);
}
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace BitonalConverter
{
public static class Converter
{
public static Bitmap ConvertToRGB(Bitmap original)
{
Bitmap newImage = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
newImage.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (Graphics g = Graphics.FromImage(newImage))
{
g.DrawImageUnscaled(original, 0, 0);
}
return newImage;
}
public static Bitmap ConvertToBitonal(Bitmap original)
{
Bitmap source = null;
// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (original.PixelFormat != PixelFormat.Format32bppArgb)
{
source = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
source.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (Graphics g = Graphics.FromImage(source))
{
g.DrawImageUnscaled(original, 0, 0);
}
}
else
{
source = original;
}
// Lock source bitmap in memory
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Copy image data to binary array
int imageSize = sourceData.Stride * sourceData.Height;
byte[] sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);
// Unlock source bitmap
source.UnlockBits(sourceData);
// Create destination bitmap
Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);
destination.SetResolution(original.HorizontalResolution, original.VerticalResolution);
// Lock destination bitmap in memory
BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
// Create destination buffer
imageSize = destinationData.Stride * destinationData.Height;
byte[] destinationBuffer = new byte[imageSize];
int sourceIndex = 0;
int destinationIndex = 0;
int pixelTotal = 0;
byte destinationValue = 0;
int pixelValue = 128;
int height = source.Height;
int width = source.Width;
int threshold = 500;
// Iterate lines
for (int y = 0; y < height; y++)
{
sourceIndex = y * sourceData.Stride;
destinationIndex = y * destinationData.Stride;
destinationValue = 0;
pixelValue = 128;
// Iterate pixels
for (int x = 0; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values) - Thanks murx
// B G R
pixelTotal = sourceBuffer[sourceIndex] + sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2];
if (pixelTotal > threshold)
{
destinationValue += (byte)pixelValue;
}
if (pixelValue == 1)
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else
{
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128)
{
destinationBuffer[destinationIndex] = destinationValue;
}
}
// Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);
// Unlock destination bitmap
destination.UnlockBits(destinationData);
// Dispose of source if not originally supplied bitmap
if (source != original)
{
source.Dispose();
}
// Return
return destination;
}
}
}

SetResolution does nothing when joining tiff images

I've been trying to adjust the resolution for a new tiff that gets created from a group of other tiffs. I would like to drop the resolution to 100x100 dpi. Everything with the join works properly but the resolution in the final tiff will always be what the resolution is of the files I am joining together (used 300x300 dpi images). I have tried using some suggestions (Set DPI value to Tiff Image in C#) for getting/setting the PropertyItems but that has failed as well. Using the join technique below, what would be the proper way to set the resolution of the final image to 100x100 dpi?
Thank you.
public byte[] JoinTiffImages(
List<byte[]> images)
{
var fPage = FrameDimension.Page;
var nearest =
System.Drawing
.Drawing2D
.InterpolationMode
.NearestNeighbor;
if (images.Count == 0)
{
throw new ImageConverterException(
"Could not join an empty set of images.");
}
else if (images.Count == 1)
{
return images[0];
}
else
{
using (var ms = new MemoryStream())
{
using (var masterBitmap =
(Bitmap)DrawingImage.FromStream(
new MemoryStream(images[0])))
{
//get the codec for tiff files
var info = GetTifCodecInfo();
var enc = Encoder.SaveFlag;
var ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter(
enc,
(long)EncoderValue.MultiFrame);
ep.Param[1] = new EncoderParameter(
Encoder.Compression,
(long)TifCompression.ToEncoderValue());
masterBitmap.SetResolution(100.0f, 100.0f);
masterBitmap.Save(ms, info, ep);
//save the intermediate frames
ep.Param[0] = new EncoderParameter(
enc,
(long)EncoderValue.FrameDimensionPage);
for (int i = 1; i < images.Count; i++)
{
using (var nextImg = (Bitmap)DrawingImage.FromStream(
new MemoryStream(images[i])))
{
for (int x = 0;
x < nextImg.GetFrameCount(fPage);
x++)
{
nextImg.SetResolution(100.0f, 100.0f);
nextImg.SelectActiveFrame(fPage, x);
masterBitmap.SaveAdd(nextImg, ep);
}
}
}
ep.Param[0] =
new EncoderParameter(
enc,
(long)EncoderValue.Flush);
//close out the file.
masterBitmap.SaveAdd(ep);
return ms.ToArray();
}
}
}
}
Here is a code that creates a multi-page tif file from a list of images.
It sets the DPI both to the master and all parts according to an input paramter.
private void saveTiff_Click(List<Image> imgList, string saveName, int dpi)
{
//all kudos to : http://bobpowell.net/generating_multipage_tiffs.aspx
foreach (Image img in imgList) ((Bitmap)img).SetResolution(dpi, dpi);
System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.SaveFlag;
Bitmap master = new Bitmap(imgList[0]);
master.SetResolution(dpi, dpi);
ImageCodecInfo info = null;
// lets hope we have an TIF encoder
foreach (ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders())
if (ice.MimeType == "image/tiff") info = ice;
// one parameter: MultiFrame
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
master.Save(saveName, info, ep);
// one parameter: further frames
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
for (int i = 1; i < imgList.Count; i++) master.SaveAdd(imgList[i], ep);
// one parameter: flush
ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
master.SaveAdd(ep);
}
I was able to resolve my issue with some help from the comments. This function will handle the resolution change without the image changing size.
public static byte[] JoinTiffImages(
List<byte[]> images,
float res)
{
var fPage = FrameDimension.Page;
var nearest =
System.Drawing
.Drawing2D
.InterpolationMode
.NearestNeighbor;
if (images.Count == 0)
{
throw new Exception(
"Could not join an empty set of images.");
}
else if (images.Count == 1)
{
return images[0];
}
else
{
var ms = new MemoryStream();
//get the codec for tiff files
var info = GetTifCodecInfo();
var ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag,
(long)EncoderValue.MultiFrame);
ep.Param[1] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Compression,
(long)EncoderValue.CompressionLZW);
using (var masterImg =
(Bitmap)System.Drawing.Image.FromStream(
new MemoryStream(images[0])))
{
using (var resizedMaster =
new Bitmap(
(int)(masterImg.Width *
(res /
masterImg.HorizontalResolution)),
(int)(masterImg.Height *
(res /
masterImg.VerticalResolution))))
{
resizedMaster.SetResolution(
res,
res);
using (var gr = Graphics.FromImage(resizedMaster))
{
gr.InterpolationMode = nearest;
gr.DrawImage(
masterImg,
new Rectangle(
0,
0,
resizedMaster.Width,
resizedMaster.Height),
0,
0,
masterImg.Width,
masterImg.Height,
GraphicsUnit.Pixel);
}
resizedMaster.Save(ms, info, ep);
//save the intermediate frames
ep.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag,
(long)EncoderValue.FrameDimensionPage);
for (int i = 1; i < images.Count; i++)
{
using (var nextImg =
(Bitmap)System.Drawing.Image.FromStream(
new MemoryStream(images[i])))
{
for (int x = 0;
x < nextImg.GetFrameCount(fPage);
x++)
{
nextImg.SelectActiveFrame(fPage, x);
using (var resizedNext =
new Bitmap(
(int)(nextImg.Width *
(res /
nextImg.HorizontalResolution)),
(int)(nextImg.Height *
(res /
nextImg.VerticalResolution))))
{
resizedNext.SetResolution(
res,
res);
using (var gr =
Graphics.FromImage(resizedNext))
{
gr.InterpolationMode = nearest;
gr.DrawImage(
nextImg,
new Rectangle(
0,
0,
resizedNext.Width,
resizedNext.Height),
0,
0,
nextImg.Width,
nextImg.Height,
GraphicsUnit.Pixel);
}
resizedMaster.SaveAdd(resizedNext, ep);
}
}
}
}
ep.Param[0] =
new EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag,
(long)EncoderValue.Flush);
//close out the file.
resizedMaster.SaveAdd(ep);
}
return ms.ToArray();
}
}
}
private static ImageCodecInfo GetTifCodecInfo()
{
foreach (var ice in ImageCodecInfo.GetImageEncoders())
{
if (ice.MimeType == "image/tiff")
{
return ice;
}
}
return null;
}

Image upload quality bad

I have an application that uploads images to a database and then show them in a webpage by using a Handler. My problem is that the images are showing in a different quality and color than the original ones. I don't know what the problem is.
File = FileUpload1.PostedFile;
imgbin = new Byte[File.ContentLength];
File.InputStream.Read(imgbin, 0, File.ContentLength);
imagename = FileUpload1.FileName;
// Here the image size is defined --------------------
System.Drawing.Image UploadedImage = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream);
UploadedImageWidth = UploadedImage.PhysicalDimension.Width;
UploadedImageHeight = UploadedImage.PhysicalDimension.Height;
//Resize Image
int compressWidth;
if (UploadedImageWidth >639)
{
compressWidth = 640;
}
else
{
compressWidth = Convert.ToInt32(UploadedImageWidth);
}
ResizeImage compressPicture = new ResizeImage();
imgbin = compressPicture.ResizeImageFile(imgbin, compressWidth);
System.Drawing.Image Image = System.Drawing.Image.FromStream(new MemoryStream(imgbin));
public class ResizeImage
{
public byte[] ResizeImageFile(byte[] imageFile, int targetSize) // Set targetSize to 1024
{
using (System.Drawing.Image oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile)))
{
Size newSize = CalculateDimensions(oldImage.Size, targetSize);
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format64bppPArgb))
{
byte[] byteArray = new byte[0];
using (Graphics canvas = Graphics.FromImage(newImage))
{
canvas.Clear(Color.White);
canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
canvas.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
int quality = 100;
ImageCodecInfo codec = RetrieveCodec("image/jpeg");
using (MemoryStream m = new MemoryStream())
{
using (EncoderParameters codeParams = new EncoderParameters())
{
using (EncoderParameter p = new EncoderParameter(Encoder.Quality, quality))
{
codeParams.Param[0] = p;
newImage.Save(m, codec, codeParams);
byteArray = m.ToArray();
}
}
}
return byteArray;
}
}
}
}
private ImageCodecInfo RetrieveCodec(string mimeType)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType == mimeType)
return codec;
}
return null;
}
public static Size CalculateDimensions(Size oldSize, int targetSize)
{
decimal ajusteTamaño;
Size newSize = new Size();
if (oldSize.Width > targetSize)
{
ajusteTamaño = oldSize.Width / Convert.ToDecimal(targetSize);
newSize.Width = (int)(oldSize.Width / ajusteTamaño);
newSize.Height = (int)(oldSize.Height / ajusteTamaño);
}
else
{
newSize.Width = oldSize.Width;
newSize.Height = oldSize.Height;
}
return newSize;
}
}

Creating 8-bit images

I'm trying to create an 8-bit image with a solid background color. It seems like it should be pretty straight forward but the details on the file list it as 32-bit color depth. What am I missing?
public void CreateImage()
{
var bmpOut = new Bitmap(300, 300);
var g = Graphics.FromImage(bmpOut);
g.FillRectangle(new SolidBrush(Color.Gray), 0, 0, 300, 300);
var stream = new MemoryStream();
bmpOut.Save(stream, GetPngCodecInfo(), GetEncoderParameters());
bmpOut.Save(#"C:\image.png", GetPngCodecInfo(), GetEncoderParameters());
}
public EncoderParameters GetEncoderParameters()
{
var parameters = new EncoderParameters();
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
return parameters;
}
public ImageCodecInfo GetPngCodecInfo()
{
var encoders = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codecInfo = null;
foreach (var imageCodecInfo in encoders)
{
if (imageCodecInfo.FormatID != ImageFormat.Png.Guid)
continue;
codecInfo = imageCodecInfo;
break;
}
return codecInfo;
}
Use this constructor to specify a pixel format : http://msdn.microsoft.com/en-us/library/3z132tat.aspx
Since you cannot create a Graphics from an indexed pixel format, you can only write raw pixels to a 8-bit image.
Bitmap bitmap = new Bitmap(32, 32, PixelFormat.Format8bppIndexed);
var bitmapData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadWrite, bitmap.PixelFormat);
Random random=new Random();
byte[] buffer=new byte[bitmap.Width*bitmap.Height];
random.NextBytes(buffer);
Marshal.Copy(buffer,0,bitmapData.Scan0,buffer.Length);
bitmap.UnlockBits(bitmapData);
bitmap.Save("test.bmp",ImageFormat.Bmp);
You can either use such code on WinForms : http://www.codeproject.com/Articles/17162/Fast-Color-Depth-Change-for-Bitmaps
Or if you can reference this class from WPF it will be much easier :
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.formatconvertedbitmap(v=vs.85).aspx
You could also create the image at a higher bit rate and then convert it to 8 bits just before saving. This would allow you to use a Graphics context when creating the image. See this question for suggestions on how to convert to 8 bits:C# - How to convert an Image into an 8-bit color Image?
ImageExtensions.cs
using System.Runtime.InteropServices;
using System.Linq;
using System.Drawing.Imaging;
using System.Drawing;
using System;
public static partial class ImageExtensions {
public static ColorPalette ToGrayScale(this ColorPalette palette) {
var entries=palette.Entries;
for(var i=entries.Length; i-->0; entries[i]=entries[i].ToGrayScale())
;
return palette;
}
public static Color ToGrayScale(this Color color, double[] luminance=null) {
var list=(luminance??new[] { 0.2989, 0.5870, 0.1140 }).ToList();
var channel=new[] { color.R, color.G, color.B };
var c=(byte)Math.Round(list.Sum(x => x*channel[list.IndexOf(x)]));
return Color.FromArgb(c, c, c);
}
public static Bitmap To8bppIndexed(this Bitmap original) {
var rect=new Rectangle(Point.Empty, original.Size);
var pixelFormat=PixelFormat.Format8bppIndexed;
var destination=new Bitmap(rect.Width, rect.Height, pixelFormat);
using(var source=original.Clone(rect, PixelFormat.Format32bppArgb)) {
var destinationData=destination.LockBits(rect, ImageLockMode.WriteOnly, pixelFormat);
var sourceData=source.LockBits(rect, ImageLockMode.ReadOnly, source.PixelFormat);
var destinationSize=destinationData.Stride*destinationData.Height;
var destinationBuffer=new byte[destinationSize];
var sourceSize=sourceData.Stride*sourceData.Height;
var sourceBuffer=new byte[sourceSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, sourceSize);
source.UnlockBits(sourceData);
destination.Palette=destination.Palette.ToGrayScale();
var list=destination.Palette.Entries.ToList();
for(var y=destination.Height; y-->0; ) {
for(var x=destination.Width; x-->0; ) {
var pixelIndex=y*destination.Width+x;
var sourceIndex=4*pixelIndex;
var color=
Color.FromArgb(
sourceBuffer[0+sourceIndex],
sourceBuffer[1+sourceIndex],
sourceBuffer[2+sourceIndex],
sourceBuffer[3+sourceIndex]
).ToGrayScale();
destinationBuffer[pixelIndex]=(byte)list.IndexOf(color);
}
}
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, destinationSize);
destination.UnlockBits(destinationData);
}
return destination;
}
}
Call bmpOut=bmpOut.To8bppIndexed(); before you it save to file.

How to create thumbnail of video using C#

i found some articles, some projects to create thumbnail of a video, using ffmpeg.exe, expression encoder
but when i downloaded the projects they are not working...
i am not getting that weather ffmpeg.exe downloaded by having problem or the projects are not working.
if anybody has other sources from where i can see samples. please post it..
-thanks in advance
Here is the class to make thumbnail of
either video or mage using ffmpeg.exe
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace Pariwaar.Controller
{
public class imageResize
{
public byte[] ResizeFromByteArray(int MaxSideSize, Byte[] byteArrayIn, string fileName)
{
byte[] byteArray = null; // really make this an error gif
MemoryStream ms = new MemoryStream(byteArrayIn);
byteArray = this.ResizeFromStream(MaxSideSize, ms, fileName);
return byteArray;
}
/// <summary>
/// converts stream to bytearray for resized image
/// </summary>
/// <param name="MaxSideSize"></param>
/// <param name="Buffer"></param>
/// <returns></returns>
public byte[] ResizeFromStream(int MaxSideSize, Stream Buffer, string fileName)
{
byte[] byteArray = null; // really make this an error gif
try
{
Bitmap bitMap = new Bitmap(Buffer);
int intOldWidth = bitMap.Width;
int intOldHeight = bitMap.Height;
int intNewWidth;
int intNewHeight;
int intMaxSide;
if (intOldWidth >= intOldHeight)
{
intMaxSide = intOldWidth;
}
else
{
intMaxSide = intOldHeight;
}
if (intMaxSide > MaxSideSize)
{
//set new width and height
double dblCoef = MaxSideSize / (double)intMaxSide;
intNewWidth = Convert.ToInt32(dblCoef * intOldWidth);
intNewHeight = Convert.ToInt32(dblCoef * intOldHeight);
}
else
{
intNewWidth = intOldWidth;
intNewHeight = intOldHeight;
}
Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
System.Drawing.Image oThumbNail = new Bitmap(ThumbNailSize.Width, ThumbNailSize.Height);
Graphics oGraphic = Graphics.FromImage(oThumbNail);
oGraphic.CompositingQuality = CompositingQuality.HighQuality;
oGraphic.SmoothingMode = SmoothingMode.HighQuality;
oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle oRectangle = new Rectangle
(0, 0, ThumbNailSize.Width, ThumbNailSize.Height);
oGraphic.DrawImage(oImg, oRectangle);
MemoryStream ms = new MemoryStream();
oThumbNail.Save(ms, ImageFormat.Jpeg);
byteArray = new byte[ms.Length];
ms.Position = 0;
ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));
oGraphic.Dispose();
oImg.Dispose();
ms.Close();
ms.Dispose();
}
catch (Exception)
{
int newSize = MaxSideSize - 20;
Bitmap bitMap = new Bitmap(newSize, newSize);
Graphics g = Graphics.FromImage(bitMap);
g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, newSize, newSize));
Font font = new Font("Courier", 8);
SolidBrush solidBrush = new SolidBrush(Color.Red);
g.DrawString("Failed File", font, solidBrush, 10, 5);
g.DrawString(fileName, font, solidBrush, 10, 50);
MemoryStream ms = new MemoryStream();
bitMap.Save(ms, ImageFormat.Jpeg);
byteArray = new byte[ms.Length];
ms.Position = 0;
ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));
ms.Close();
ms.Dispose();
bitMap.Dispose();
solidBrush.Dispose();
g.Dispose();
font.Dispose();
}
return byteArray;
}
/// <summary>
/// Saves the resized image to specified file name and path as JPEG
/// and also returns the bytearray for any other use you may need it for
/// </summary>
/// <param name="MaxSideSize"></param>
/// <param name="Buffer"></param>
/// <param name="fileName">No Extension</param>
/// <param name="filePath">Examples: "images/dir1/dir2" or "images" or "images/dir1"</param>
/// <returns></returns>
public byte[] SaveFromStream(int MaxSideSize, Stream Buffer, string ErrorMessage, string filePath, string ThumbnailPath)
{
byte[] byteArray = null; // really make this an error gif
try
{
Bitmap bitMap = new Bitmap(Buffer);
int intOldWidth = bitMap.Width;
int intOldHeight = bitMap.Height;
int intNewWidth;
int intNewHeight;
int intMaxSide;
if (intOldWidth >= intOldHeight)
{
intMaxSide = intOldWidth;
}
else
{
intMaxSide = intOldHeight;
}
if (intMaxSide > MaxSideSize)
{
//set new width and height
double dblCoef = MaxSideSize / (double)intMaxSide;
intNewWidth = Convert.ToInt32(dblCoef * intOldWidth);
intNewHeight = Convert.ToInt32(dblCoef * intOldHeight);
}
else
{
intNewWidth = intOldWidth;
intNewHeight = intOldHeight;
}
Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
System.Drawing.Image oThumbNail = new Bitmap(ThumbNailSize.Width, ThumbNailSize.Height);
Graphics oGraphic = Graphics.FromImage(oThumbNail);
oGraphic.CompositingQuality = CompositingQuality.HighQuality;
oGraphic.SmoothingMode = SmoothingMode.HighQuality;
oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle oRectangle = new Rectangle
(0, 0, ThumbNailSize.Width, ThumbNailSize.Height);
oGraphic.DrawImage(oImg, oRectangle);
//Save File
string newFileName = filePath;
oThumbNail.Save(newFileName, ImageFormat.Jpeg);
MemoryStream ms = new MemoryStream();
oThumbNail.Save(ms, ImageFormat.Jpeg);
//--- done by vrunda create thmbnail
System.Drawing.Image.GetThumbnailImageAbort dummyCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
System.Drawing.Image thumbNailImg =oThumbNail.GetThumbnailImage(100, 100, dummyCallBack, IntPtr.Zero);
thumbNailImg.Save(ThumbnailPath, ImageFormat.Jpeg);
//----- done by vrunda
byteArray = new byte[ms.Length];
ms.Position = 0;
ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));
oGraphic.Dispose();
oImg.Dispose();
ms.Close();
ms.Dispose();
}
catch (Exception)
{
int newSize = MaxSideSize - 20;
Bitmap bitMap = new Bitmap(newSize, newSize);
Graphics g = Graphics.FromImage(bitMap);
g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, newSize, newSize));
Font font = new Font("Courier", 8);
SolidBrush solidBrush = new SolidBrush(Color.Red);
g.DrawString("Failed To Save File or Failed File ", font, solidBrush, 10, 5);
g.DrawString(ErrorMessage, font, solidBrush, 10, 50);
MemoryStream ms = new MemoryStream();
bitMap.Save(ms, ImageFormat.Jpeg);
byteArray = new byte[ms.Length];
ms.Position = 0;
ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));
ms.Close();
ms.Dispose();
bitMap.Dispose();
solidBrush.Dispose();
g.Dispose();
font.Dispose();
}
return byteArray;
}
public bool ThumbnailCallback()
{
return false;
}
}
}
here is the link of working ffmpeg sample
http://www.codeproject.com/Articles/241399/Convert-Video-to-Flash-Video-flv-and-progressive-s
hopefully this might help you

Categories