Answered by:
Resize Large Image into Thumbnail

Question
-
hi,
I need some help on how to resize image size ( ie 1 -3 MB filesize ) into Thumbnail . And this thumbnail can be any size like 100x100, 300x300 ...)
Can it be done using some kind of imageFactory?? Would appreciate if you can provide some code to follow.
Thanks
Peace is the fruit of LoveWednesday, March 24, 2010 6:15 AM
Answers
-
Ok, home again. First thing, You'll need this class:
public class IImaging { #region stałe i struktury public enum PixelFormatID : int { PixelFormatIndexed = 0x00010000, PixelFormatGDI = 0x00020000, PixelFormatAlpha = 0x00040000, PixelFormatPAlpha = 0x00080000, PixelFormatExtended = 0x00100000, PixelFormatCanonical = 0x00200000, PixelFormatUndefined = 0, PixelFormatDontCare = 0, PixelFormat1bppIndexed = (1 | (1 << 8) | PixelFormatIndexed | PixelFormatGDI), PixelFormat4bppIndexed = (2 | (4 << 8) | PixelFormatIndexed | PixelFormatGDI), PixelFormat8bppIndexed = (3 | (8 << 8) | PixelFormatIndexed | PixelFormatGDI), PixelFormat16bppRGB555 = (5 | (16 << 8) | PixelFormatGDI), PixelFormat16bppRGB565 = (6 | (16 << 8) | PixelFormatGDI), PixelFormat16bppARGB1555 = (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI), PixelFormat24bppRGB = (8 | (24 << 8) | PixelFormatGDI), PixelFormat32bppRGB = (9 | (32 << 8) | PixelFormatGDI), PixelFormat32bppARGB = (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical), PixelFormat32bppPARGB = (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI), PixelFormat48bppRGB = (12 | (48 << 8) | PixelFormatExtended), PixelFormat64bppARGB = (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended), PixelFormat64bppPARGB = (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended), PixelFormatMax = 15 } public enum BufferDisposalFlag : int { BufferDisposalFlagNone, BufferDisposalFlagGlobalFree, BufferDisposalFlagCoTaskMemFree, BufferDisposalFlagUnmapView } public enum InterpolationHint : int { InterpolationHintDefault, InterpolationHintNearestNeighbor, InterpolationHintBilinear, InterpolationHintAveraging, InterpolationHintBicubic } public struct BitmapData { public uint Width; public uint Height; public int Stride; public PixelFormatID PixelFormat; public IntPtr Scan0; public IntPtr Reserved; } public struct ImageInfo { public uint GuidPart1; public uint GuidPart2; public uint GuidPart3; public uint GuidPart4; public PixelFormatID pixelFormat; public uint Width; public uint Height; public uint TileWidth; public uint TileHeight; public double Xdpi; public double Ydpi; public uint Flags; } #endregion #region interfejsy [ComImport, Guid("327ABDA7-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IImagingFactory { uint CreateImageFromStream(IStream stream, out IImage image); uint CreateImageFromFile(string filename, out IImage image); uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint size, BufferDisposalFlag disposalFlag, out IImage image); uint CreateNewBitmap(uint width, uint height, PixelFormatID pixelFormat, out IBitmapImage bitmap); uint CreateBitmapFromImage(IImage image, uint width, uint height, PixelFormatID pixelFormat, InterpolationHint hints, out IBitmapImage bitmap); uint CreateBitmapFromBuffer(BitmapData bitmapData, out IBitmapImage bitmap); uint CreateImageDecoder(); // pominięte uint CreateImageEncoderToStream(); // pominięte uint CreateImageEncoderToFile(); // pominięte uint GetInstalledDecoders(); // pominięte uint GetInstalledEncoders(); // pominięte uint InstallImageCodec(); // pominięte uint UninstallImageCodec(); // pominięte } [ComImport, Guid("327ABDA9-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IImage { uint GetPhysicalDimension(out Size size); uint GetImageInfo(out ImageInfo info); uint SetImageFlags(uint flags); uint Draw(IntPtr hdc, ref Rectangle dstRect, IntPtr srcRect); uint PushIntoSink(); // pominięte uint GetThumbnail(uint thumbWidth, uint thumbHeight, out IImage thumbImage); } [ComImport, Guid("327ABDAA-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IBitmapImage { uint GetSize(out Size size); uint GetPixelFormatID(out PixelFormatID pixelFormat); uint LockBits(ref Rectangle rect, uint flags, PixelFormatID pixelFormat, out BitmapData lockedBitmapData); uint UnlockBits(ref BitmapData lockedBitmapData); uint GetPalette(); // pominięte uint SetPalette(); // pominięte } [ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IStream { void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbRead); void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbWritten); void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition); void SetSize(long libNewSize); void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten); void Commit(int grfCommitFlags); void Revert(); void LockRegion(long libOffset, long cb, int dwLockType); void UnlockRegion(long libOffset, long cb, int dwLockType); void Stat(); // pominięte void Clone(out IStream ppstm); } #endregion #region metody public static IImagingFactory CreateFactory() { return (IImagingFactory)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("327ABDA8-072B-11D3-9D7B-0000F81EF32E"))); } #endregion }
It's 80% implementation of IImaging API. I've skipped some methods (the ones with "// pominięte" :)) because those require more playing with structures and interfaces than it's worth.
Now all You need to do is to:
IImagingFactory factory = IImaging.CreateFactory(); IImage image; IImage thumbnail; factory.CreateImageFromFile(path, out image); image.GetThumbnail(100, 100, out thumbnail); Image img = new Bitmap(100, 100); Rectangle rect = new Rectangle(img.Width, img.Height); using(Graphics g = Graphics.FromImage(img)) { IntPtr hdc = g.GetHdc(); thumbnail.Draw(hdc, ref rect, IntPtr.Zero); g.ReleaseHdc(hdc); } thumbnail.Release(); image.Release(); factory.Release();
First thing, I'm initializing the factory and getting an image from the path. After that I'm creating a thumbnail and creating a bitmap (managed) which will serve as a managed 'canvas' for our thumbnail. Next I'm getting HDC of that 'canvas' and paint upon it our thumbnail from IImage.
Now You can do whatever You wish with a managed bitmap 'containing' Your thumbnail (save, draw etc.).
Hope it's clean enough to understand.
If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting.
I'm on MSDN just like MD House in the clinic. But I'm also a human which sometimes needs to see another doctor :)- Proposed as answer by Mal Loth Wednesday, March 24, 2010 5:28 PM
- Marked as answer by warrentang Tuesday, March 30, 2010 2:47 AM
Wednesday, March 24, 2010 5:26 PM
All replies
-
Simply use IImage::GetThumbnail from IImaging interface.
Use this like this:
IImagingFactory* factory = NULL;
IImage* image = NULL;
IImage* thumbnail = NULL;
if(CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, __uuidof(IImagingFactory), (void **)&factory) >= 0)
{
factory->CreateImageFromFile(path, &image);
image->GetThumbnail(100, 100, &thumbnail);
... // do something with that thumbnail (thumbnail->Draw etc.)
thumbnail->Release();
image->Release();
factory->Release();
}
If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting.
I'm on MSDN just like MD House in the clinic. But I'm also a human which sometimes needs to see another doctor :)- Proposed as answer by Mal Loth Wednesday, March 24, 2010 7:13 AM
Wednesday, March 24, 2010 7:12 AM -
Hi,
Thank for the info and help.
Would appreciate if you can give me a sample in C# so I can follow al the Pinvoke stuff.
Thanks
Peace is the fruit of LoveWednesday, March 24, 2010 11:13 AM -
Hi,
Check this discussion:
http://www.dotnetcurry.com/(S(crjdoz45pshacq455xkha145)X(1))/ShowArticle.aspx?ID=140
Also you can try this (this may help you, even thought its desktop version)
http://blogs.msdn.com/acoat/archive/2007/05/09/resize-images-a-thumbnail-maker.aspx
This may better suit for your requirement:
http://blog.opennetcf.com/ayakhnin/PermaLink,guid,b1d16e2e-97ee-4fd1-9e3c-4378c86751fb.aspx
Regards,
Malleswar
- Proposed as answer by Malleswara Reddy [MCTS, MCP] Thursday, March 25, 2010 5:09 AM
Wednesday, March 24, 2010 11:43 AM -
Hi all ,
Thank for the info.
Malleswar,
I have tried the links you suggested. They won't work for NetCF IF IMAGE SIZE > 1 MB.
I think the only solution is from Mal Loth:
http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/337a210b-ba43-4f2a-b5a3-4121fae7de
But I dont quite sure how to use the code. I hope to see a good sample using this technique as I believe it can handle IMAGE SIZE > 1 MB .
Thanks
Please help.
Peace is the fruit of LoveWednesday, March 24, 2010 1:24 PM -
I'll answer as soon as I'll get back from work...
If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting.
I'm on MSDN just like MD House in the clinic. But I'm also a human which sometimes needs to see another doctor :)Wednesday, March 24, 2010 3:21 PM -
Ok, home again. First thing, You'll need this class:
public class IImaging { #region stałe i struktury public enum PixelFormatID : int { PixelFormatIndexed = 0x00010000, PixelFormatGDI = 0x00020000, PixelFormatAlpha = 0x00040000, PixelFormatPAlpha = 0x00080000, PixelFormatExtended = 0x00100000, PixelFormatCanonical = 0x00200000, PixelFormatUndefined = 0, PixelFormatDontCare = 0, PixelFormat1bppIndexed = (1 | (1 << 8) | PixelFormatIndexed | PixelFormatGDI), PixelFormat4bppIndexed = (2 | (4 << 8) | PixelFormatIndexed | PixelFormatGDI), PixelFormat8bppIndexed = (3 | (8 << 8) | PixelFormatIndexed | PixelFormatGDI), PixelFormat16bppRGB555 = (5 | (16 << 8) | PixelFormatGDI), PixelFormat16bppRGB565 = (6 | (16 << 8) | PixelFormatGDI), PixelFormat16bppARGB1555 = (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI), PixelFormat24bppRGB = (8 | (24 << 8) | PixelFormatGDI), PixelFormat32bppRGB = (9 | (32 << 8) | PixelFormatGDI), PixelFormat32bppARGB = (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical), PixelFormat32bppPARGB = (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI), PixelFormat48bppRGB = (12 | (48 << 8) | PixelFormatExtended), PixelFormat64bppARGB = (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended), PixelFormat64bppPARGB = (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended), PixelFormatMax = 15 } public enum BufferDisposalFlag : int { BufferDisposalFlagNone, BufferDisposalFlagGlobalFree, BufferDisposalFlagCoTaskMemFree, BufferDisposalFlagUnmapView } public enum InterpolationHint : int { InterpolationHintDefault, InterpolationHintNearestNeighbor, InterpolationHintBilinear, InterpolationHintAveraging, InterpolationHintBicubic } public struct BitmapData { public uint Width; public uint Height; public int Stride; public PixelFormatID PixelFormat; public IntPtr Scan0; public IntPtr Reserved; } public struct ImageInfo { public uint GuidPart1; public uint GuidPart2; public uint GuidPart3; public uint GuidPart4; public PixelFormatID pixelFormat; public uint Width; public uint Height; public uint TileWidth; public uint TileHeight; public double Xdpi; public double Ydpi; public uint Flags; } #endregion #region interfejsy [ComImport, Guid("327ABDA7-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IImagingFactory { uint CreateImageFromStream(IStream stream, out IImage image); uint CreateImageFromFile(string filename, out IImage image); uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint size, BufferDisposalFlag disposalFlag, out IImage image); uint CreateNewBitmap(uint width, uint height, PixelFormatID pixelFormat, out IBitmapImage bitmap); uint CreateBitmapFromImage(IImage image, uint width, uint height, PixelFormatID pixelFormat, InterpolationHint hints, out IBitmapImage bitmap); uint CreateBitmapFromBuffer(BitmapData bitmapData, out IBitmapImage bitmap); uint CreateImageDecoder(); // pominięte uint CreateImageEncoderToStream(); // pominięte uint CreateImageEncoderToFile(); // pominięte uint GetInstalledDecoders(); // pominięte uint GetInstalledEncoders(); // pominięte uint InstallImageCodec(); // pominięte uint UninstallImageCodec(); // pominięte } [ComImport, Guid("327ABDA9-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IImage { uint GetPhysicalDimension(out Size size); uint GetImageInfo(out ImageInfo info); uint SetImageFlags(uint flags); uint Draw(IntPtr hdc, ref Rectangle dstRect, IntPtr srcRect); uint PushIntoSink(); // pominięte uint GetThumbnail(uint thumbWidth, uint thumbHeight, out IImage thumbImage); } [ComImport, Guid("327ABDAA-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IBitmapImage { uint GetSize(out Size size); uint GetPixelFormatID(out PixelFormatID pixelFormat); uint LockBits(ref Rectangle rect, uint flags, PixelFormatID pixelFormat, out BitmapData lockedBitmapData); uint UnlockBits(ref BitmapData lockedBitmapData); uint GetPalette(); // pominięte uint SetPalette(); // pominięte } [ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [ComVisible(true)] public interface IStream { void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbRead); void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbWritten); void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition); void SetSize(long libNewSize); void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten); void Commit(int grfCommitFlags); void Revert(); void LockRegion(long libOffset, long cb, int dwLockType); void UnlockRegion(long libOffset, long cb, int dwLockType); void Stat(); // pominięte void Clone(out IStream ppstm); } #endregion #region metody public static IImagingFactory CreateFactory() { return (IImagingFactory)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("327ABDA8-072B-11D3-9D7B-0000F81EF32E"))); } #endregion }
It's 80% implementation of IImaging API. I've skipped some methods (the ones with "// pominięte" :)) because those require more playing with structures and interfaces than it's worth.
Now all You need to do is to:
IImagingFactory factory = IImaging.CreateFactory(); IImage image; IImage thumbnail; factory.CreateImageFromFile(path, out image); image.GetThumbnail(100, 100, out thumbnail); Image img = new Bitmap(100, 100); Rectangle rect = new Rectangle(img.Width, img.Height); using(Graphics g = Graphics.FromImage(img)) { IntPtr hdc = g.GetHdc(); thumbnail.Draw(hdc, ref rect, IntPtr.Zero); g.ReleaseHdc(hdc); } thumbnail.Release(); image.Release(); factory.Release();
First thing, I'm initializing the factory and getting an image from the path. After that I'm creating a thumbnail and creating a bitmap (managed) which will serve as a managed 'canvas' for our thumbnail. Next I'm getting HDC of that 'canvas' and paint upon it our thumbnail from IImage.
Now You can do whatever You wish with a managed bitmap 'containing' Your thumbnail (save, draw etc.).
Hope it's clean enough to understand.
If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting.
I'm on MSDN just like MD House in the clinic. But I'm also a human which sometimes needs to see another doctor :)- Proposed as answer by Mal Loth Wednesday, March 24, 2010 5:28 PM
- Marked as answer by warrentang Tuesday, March 30, 2010 2:47 AM
Wednesday, March 24, 2010 5:26 PM -
Hi Mal Loth,
Thank so much for the help. This is really a light in a tunner. I have been searching the web and unable to get any info relating to this.
I am working on it now and will let you know the outcome.
Thanks
Peace is the fruit of LoveThursday, March 25, 2010 1:27 AM -
Hi Mal Loth,
I have tested the code. The code did not produce any Thumbnail. What have I done wrong? Please help.
This was what I had done as follows:1. in the project, add a a Class and name it IImaging.cs
using System;
using System.Drawing;
using System.Runtime.InteropServices;class IImaging
{// place all your code here
}
2. In the project, add a Form with a button
Private void btnCreate_Click(object sender, EventArgs e)
{//-- 1----Use the images in the Emulator for testing to create Thumbnail.
strFileName = @"\My Documents\My Pictures\Flower.jpg";
//-- 2.--- Add IImaging , if not it will give error msg:
// and calling the static method.
IImaging.IImagingFactory factory = IImaging.CreateFactory();
IImaging.IImage image;
IImaging.IImage thumbnail;
factory.CreateImageFromFile(strFileName, out image);
image.GetThumbnail(100, 100, out thumbnail);
Image img = new Bitmap(100, 100);Rectangle rect = new Rectangle(10,10,img.Width, img.Height);
using (Graphics g = Graphics.FromImage(img))
{
IntPtr hdc = g.GetHdc();
thumbnail.Draw(hdc, ref rect, IntPtr.Zero);
g.ReleaseHdc(hdc);
}//---3-- Release() : These will give error msg :
These release thing need to be commented out as it will throw error msg:
Example : IImaging.IImage' does not contain a definition for 'Release'//thumbnail.Release();
//image.Release();
//factory.Release();}
Questions:4) I noticed you have a static method in this class. So, should I make this class a static Class?
5) No Thumbnail created when run on emulator for testing. What I did not follow?
I am using NetCF2 sp1 and VS2005 ob Win XP.
6) How do I get the Width and Height of the image ( such as Flower.jpg in Emulator) ??
Thanks
Peace is the fruit of LoveThursday, March 25, 2010 5:01 AM -
And again, You'll have to wait till I'll come back from work...
Try playing with the Draw method, especially its ref Rectangle parameter.
You can skip releases - at least for now.
As for the image size, You'd have to first load it into an Image class to get its resolution (width x height).
And one more thing:
Rectangle rect = new Rectangle(0, 0, img.Width, img.Height); <- and rectangle must be exacly like the thumbnail You wish to put into.
If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting.
I'm on MSDN just like MD House in the clinic. But I'm also a human which sometimes needs to see another doctor :)Thursday, March 25, 2010 7:23 AM -
Hi,
Have changed it to this :Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
But still it wont create any thumbnail. Can you see what I have done wrong.
Thanks
Peace is the fruit of LoveThursday, March 25, 2010 11:18 PM -
You may like to try out the OpenNETCF.Drawing.ImageUtils.CreateThumbnail in OpenNETCF SDF. It is a ready-made wrapper which can save you a lot of trouble. It should be quite easy to use but a sample is available here: http://blog.opennetcf.com/afeinman/CommentView,guid,8fb585db-bd44-42fe-afa9-07b116c6d2ba.aspx
Please mark the post that helps you, and unmark that does not. This benefits our community.Friday, March 26, 2010 3:07 AM -
Hi,
Thank for the link. It is certainly comes in handy.
However, I would like to try to learn to use the IImagefactory way first to enhence my understanding how things works.
I am still working out my problem and still waiting for the solution to my problem.
Thanks
Peace is the fruit of LoveFriday, March 26, 2010 3:56 AM