Converting animated .gif file into a .bmp strip - c#

I was wondering if someone can direct me or guide me in order to use a .gif image and convert it into a .bmp strip image file.

First, you need to get the gif's size. Then you need to find out how many frames there are.
After that you need to create a new image with Height = original height, and Width = Frames * Gif Width.
Then you must paste the original Gif's frames into the strip like so: Frame N starts at pixel N*Width.
That is if you're making a horizontal strip.
And here is the complete code for a console application:
using System.Drawing;
using System.Drawing.Imaging;
foreach (var arg in args)
{
Image gif = Image.FromFile(arg);
FrameDimension dim = new FrameDimension(gif.FrameDimensionsList[0]);
int frames = gif.GetFrameCount(dim);
Bitmap resultingImage = new Bitmap(gif.Width * frames, gif.Height);
for (int i = 0; i < frames; i++)
{
gif.SelectActiveFrame(dim, i);
Rectangle destRegion = new Rectangle(gif.Width * i, 0, gif.Width, gif.Height);
Rectangle srcRegion = new Rectangle(0, 0, gif.Width, gif.Height);
using (Graphics grD = Graphics.FromImage(resultingImage))
{
grD.DrawImage(gif, destRegion, srcRegion, GraphicsUnit.Pixel);
}
}
resultingImage.Save("res.png", ImageFormat.Png);
}
The resulting image is saved in the compiled console app binary file directory under the name res.png. You can make the app save the resulting image right where the source file is, ask whether to make a horizontal or vertical strip, etc.

Making an image strip can be easily done with Photoshop (you can get a free trial version, or Elements)
Open .gif - Photoshop will open each frame as a layer
Resize canvas to (height of the gif * layers) pixels
Remove all frame information, keep layers
Select last layer, and move it to very bottom
Select all layers and click 'Distribute vertical centers'. Now you have a perfectly arranged strip.
If you are using Photoshop, you can just export as BMP. Thats it.

The method what works for sure is:
Download an install Easy GIF Animator
Open tour gif with it and export the frames to separate files
Download and install any program which can create the layers (eg. Photoshop CS3 Little)
Create a new file width as your picture; Height = Height of Your pic. X number of pictures
Copy each pic. as a layers in to Your new file and move them one after the other.
Save it as a .png file
Download an install iPAQ 31x Image Explorer
Open Your .png in it
Save it as aRGB file (normal BMP may don't work)
DONE!!
Maybe it's not the easiest method but it gives the possibility of precise editing and allows you to make strips of icons that are on a transparent background (but not limited to icons)

Just load .gif in Bitmap and save it in .bmp. If you want to export the frames of .gif I have no idea how to do this. You can have look at this www.eggheadcafe.com/articles/stripimagefromanimatedgif.asp, it seems to be what what you're looking for.

Related

ZedGraph to PDF using MigraDoc

I am currently working on a C# application that aims to do some computation and output graphs in a pdf file.
I use the Zedgraph library to draw my graphs so something like graphPane.AddCurve(PointPairList). Now I tried to output these graphs to pdf file via MigraDoc package.
Currently, I have a script that map the Zedgraph to bitmap then paste it on the pdf file. So something like this:
private Bitmap getBitMap()
{
ZedGraphControl graph = new ZedGraphControl();
newGraph = graphPane.Clone();
SizeF s = new SizeF(3.5f, 4.5f);
newGraph.Scale(s);
newGraph.DrawToBitmap(bit, new Rectangle(0, 0, newGraph.Width, newGraph.Height));
return bit;
}
The problem is that this give me a slightly pixellated image on the pdf page. And I need this graph to be in a very high quality. So are there anything I can change the improve the quality or do i have to change my entire approach for such thing.
Thank you so much in advance.
By default a Bitmap you create has your current screen resolution which could be as low as 75dpi, more common 96dpi; more modern monitors have 120dpi or more, but a good print quality starts 150dpi. For really crips images you want 300dpi and to allow zooming you may want to have 600dpi or more..
So you need to create and fill a bitmap with a larger size and take control of its dpi resolution.
Assuming your size of 3.5f x 4.5f is inches, for 300dpi you need a Bitmap with 1050 x 1350 pixels.
So you should create such a Bitmap..:
Bitmap bmp = new Bitmap(1050, 1350);
..and set the resolution:
bmp.SetResolution(300, 300);
To fill it up your control must have the same size:
newGraph.ClientSize = bmp.Size;
Now DrawToBitmap should create an image that is crisp and fit to zoom in..
Note that it does not matter if the control is too large to fit on the screen; DrawToBitmap will still work.
Update In addidtion to a sufficient resolution it is of interest to draw quality lines etc.. A speciality of ZedGraph is that one can turn on Antialiasing, either for individual lines:
curve_x.Line.IsAntiAlias = true;
or other elements:
myPane.XAxis.Scale.FontSpec.IsAntiAlias = true;
or the whole Chart:
zedGraphControl1.IsAntiAlias = true;
All examples are taken from this post.

How to draw vector graphics and save it in PDF file?

I'm working on a project which generally is collecting data and drawing results in charts. (Using C#) I need to save my charts in a PDF file. My question is, how to save charts in a PDF file without loosing resolution? My point is how to draw vector graphics instead of raster graphics?
I tried iTextSharp to create PDF file but the result is not satisfying at all!
I'm new here, so I'm not able to upload pictures.
Here is the result after saving my file:
https://www.dropbox.com/s/ruwtc82hfosxk6y/Test.pdf?dl=0
Here is the PDF that I need to create:
https://www.dropbox.com/s/jvu5uu069imo9xc/nir%20well%20abfar.pdf?dl=0
There are two ways I know of to get high-quality images from your Chart into a PDF.
One is by using vector formats:
Use chart.SaveImage with one of the three emf formats.
Convert the resulting emf file to wmf
Insert the wmf file into your iTextSharp document.
1 and 3 are one-liners. But step 2 is not. In fact I haven't found a working c# solution at all. The best was a weird reference to an edit that has disappeared here ..
If you can use some other program to do the conversion you will get nice results like this demo pdf file.. I used Illustrator for the conversion.
Two: If you can't get step 2 to work, you can still get nice results, if you use raster images with a nice and high resolution. Here is how to do it:
First we hide the Chart, so we don't scare the user. Then we make it as large as we want the output to be. Then we DrawToBitmap and finally we reset the chart again..:
Size s = chart1.Size;
chart1.Hide();
// pick your size in pixels
// I simply multiply my screen size..:
chart1.Size = new System.Drawing.Size(s.Width * 5, s.Height * 5);
using (Bitmap bmp = new Bitmap(chart1.ClientSize.Width, chart1.ClientSize.Height))
{
// you should set the resolution,
// although I didn't find a way for iTextSharp to use it visually
bmp.SetResolution(600, 600);
using (Graphics G = Graphics.FromImage(bmp))
{
G.SmoothingMode = SmoothingMode.HighQuality;
G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
chart1.DrawToBitmap(bmp, chart1.ClientRectangle);
bmp.Save(yourImageFile, ImageFormat.Png);
}
}
chart1.Size = s;
chart1.Show();
You could also use SaveImage and save a few lines, but you can't set the resolution of the png file there and it will be saved at the currnt screen resolution, which is 96dpi here..
Now you have a large image and will probably have to scale it down in iTextSharp:
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(yourImageFile);
img .ScalePercent(15); // scale to fit your needs..
doc.Add(img );
Note that the legend and the labels get very small this way, so you may have to enlarge them before saving. I also found that, when scaling down, the image is rather bright until you zoom in..
Here are two screenshots, one from the chart, the other from the pdf documnet after zooming in a lot (300%)..:

.NET C# - Both Bitmap and Image Loads Images Smaller than Expected

I'm trying to process the typical 16 megapixel images from a modern camera. Picking a random image, both the file system and my image editing software says the image is 4608 x 3456. When I load the image in C# (VS2013 .Net 4.5) using either new Bitmap(filename) or Image.FromFile(filename), I get an image successfully loaded. However, the resulting image has a size of 1613 x 1210. Now, in some cases I want to create custom size thumbnails, and this will work ok. However, I have another need where I detect "non normal" orientations and I simply want to flip/rotate for display, then save.
Saving these images (without any adjustments, just load and save) creates a valid image on disk. However, both the file system AND my image tool says the size is 1613 x 1210.
How do I load the full size image and preserve all info back to disk? Any ideas as to what I'm doing wrong? I just want to rotate the image where needed, I don't want to shrink it!
Here's a snippet of what I tried, as promised in a comment below:
Bitmap bm = new Bitmap(fileName);
Image jpg = Image.FromFile(fileName);
jpg.Save("e:\\test.jpg");
bm.Save("e:\\test2.jpg");
Both files are smaller than their original size, and match the width and height the debugger shows for both in-memory images.
Per a suggested answer, I tried this code but saw no difference in the results:
long width = 0;
long height = 0;
byte[] imageBytes = File.ReadAllBytes(fileName);
using (MemoryStream ms = new MemoryStream(imageBytes))
{
Image jpg3 = Image.FromStream(ms);
width = jpg3.Width;
height = jpg3.Height;
jpg3.Save("e:\\test3.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
Thanks in advance.
[EDIT]
User Error from a followup post:
While it's true I do have a 4608x3456 size image of the very picture I
am trying to load, I selected the wrong directory in my OpenFileDialog
and was actually selected a, you guessed it, 1613 x 1210 version of
this image. The code WAS loading the full thing, the silly operator
(me) was gumming it up.
Before I post, I'll try the full-size image ... yeah, it works fine.
Can you show your program code?
I downloaded 5169x3423 size sample image.
Load this image using program and when i restored it, original and new image are same.
I load image file to byte array and save it to Bitmap.
private Image LoadImage()
{
OpenFileDialog openFile = new OpenFileDialog();
openFile.ShowDialog();
byte[] byteImage = File.ReadAllBytes(openFile.FileName);
Image myImage;
using (var ms = new MemoryStream(byteImage))
{
myImage = Image.FromStream(ms);
}
return myImage;
}
private void SaveImage(Image myImage)
{
Bitmap bmp = new Bitmap(myImage);
// Temp save location
bmp.Save("c:\\test\\myImage.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}

Is there a workaround for overlaying transparent images from resources?

Right now I have a form with a PictureBox on the form. I'm using two partially transparent images and trying to put one on top of the other.
sideMenuWide = rounded rectangle with transparent background (.png) [Bottom image]
labelPointer = triangle with transparent background (.png) [Top image]
Here is my approach:
// METHOD #1 //
Image img1 = Image.FromFile(#"C:\sideMenuWide.png");
Image img2 = Image.FromFile(#"C:\labelPointer.png");
picBox.Image = CombineImages(img1, img2);
// METHOD #2 //
Image imgA = RBS.Properties.Resources.sideMenuWide;
Image imgB = RBS.Properties.Resources.labelPointer;
picBox.Image = CombineImages(imgA, imgB);
And the CombineImage function: (I did not write this function, only modified)
public static Bitmap CombineImages(Image imgA, Image imgB)
{
//a holder for the result (By default, use the first image as the main size)
Bitmap result = new Bitmap(imgA.Size.Width, imgA.Size.Height);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the images into the target bitmap
graphics.DrawImage(imgA, 0, 0, imgA.Width, imgA.Height);
graphics.DrawImage(imgB, 100, 70, imgB.Width, imgB.Height);
}
return result;
}
Method #1 DOES work how I want it to, displays imgB perfectly on top of imgA.
Method #2 however shows imgA just fine but imgB is really faint.
Any ideas on how to overcome this? I would like to be able to do this using Resources instead of having to pull from a file.
If the files work when loaded, but the resources don't, then it sounds like the resx build process or the ResourceManager is doing something undesirable. I'd try embedding the files and reading them directly from a stream rather than relying on the ResourceManager to do it for you.
In your Solution Explorer, Add Existing File to add the file to your project. Get properties on the added file and set it to Embedded Resource=. (Don't add it to a resx file)
In your code, you can now get a stream containing the file's data:
Stream instream = Assembly.GetExecutingAssembly().
GetManifestResourceStream("RBS.labelPointer.png"));
(Hint: The compiler generates an obtuse name for the embedded resource, so after adding the files you can add temporary code to call Assembly.GetExecutingAssembly().GetManifestResourceNames() to get a list of them all and find the file you're interested in)
Load your bitmap/image from the stream:
Image img2 = new Bitmap(inStream);

Overlay two or more Bitmaps to show in Picturebox (C#)

In my C# program I have a Picturebox in which i want to show a stream of video (consecutive frames). I receive raw data, that I then transform into Bitmap or Image. I can show one image at a time without a problem (to reproduce the video stream).
Now my issue is that I want to merge 2 or more bitmaps (like layers) with the same size and alpha values (ARGB) and show it on the picturebox.
I have read lots of websites and posts here on SO, but many use the Graphics class, and I just can't draw it on my application (very likely because i'm new to C#! and already have my program setup, so I didn't want to change the structure).
What i need (to know):
How to overlay two or more Bitmaps with alpha values;
NO pixel manipulation please, can't afford that cost in performance.
Thank you so much in advance!
NOTE: I think this question shouldn't be marked (or closed) as duplicate, because everything i found in SO is done either with pixel manipulation or through the Graphics class. (but I might be wrong!)
EDIT: Possible workaround (NOT the solution to the question)
In
A PictureBox Problem, the 4th answer (from user comecme) tells me to have 2 picturebox, one on top of the other. The only (extra) thing I had to do to make it work with this approach was:
private void Form1_Load(object sender, EventArgs e)
{
pictureBox2.Parent = pictureBox1;
}
Where pictureBox2 will be the one on top.
I won't consider this an answer to this problem, because I consider it a workaround (specially because having more than 10 pictureboxes doesn't seem ideal! lol). That's why I will leave this question opened waiting for a real answer to my question.
EDIT: Resolved! check my answer.
Here is the real answer to my problem.
1) Use a List<Bitmap> to store all the images you want to blend;
2) Create a new Bitmap to hold the final image;
3) Draw each image on top of the final image's graphics using the using statement.
The code:
List<Bitmap> images = new List<Bitmap>();
Bitmap finalImage = new Bitmap(640, 480);
...
//For each layer, I transform the data into a Bitmap (doesn't matter what kind of
//data, in this question) and add it to the images list
for (int i = 0; i < nLayers; ++i)
{
Bitmap bitmap = new Bitmap(layerBitmapData[i]));
images.Add(bitmap);
}
using (Graphics g = Graphics.FromImage(finalImage))
{
//set background color
g.Clear(Color.Black);
//go through each image and draw it on the final image (Notice the offset; since I want to overlay the images i won't have any offset between the images in the finalImage)
int offset = 0;
foreach (Bitmap image in images)
{
g.DrawImage(image, new Rectangle(offset, 0, image.Width, image.Height));
}
}
//Draw the final image in the pictureBox
this.layersBox.Image = finalImage;
//In my case I clear the List because i run this in a cycle and the number of layers is not fixed
images.Clear();
Credits go to Brandon Cannaday in this tech.pro webpage.

Categories