views:

103

answers:

4

I need the easy to learn & fast method for generating image from background image, texts and after that saving as JPEG format.

What you can suggest? Any library or tutorial on this? Important criteria is simpleness.

+4  A: 

I usually do this using GDI+. There are lots of tutorials on this on the net, but basically what you need to do is something like this:

using(Image image = new Bitmap(Width, Height))
using (Graphics g = Graphics.FromImage(image)) {
  g.Draw....
  g.Draw....
  image.Save(filename, ImageFormat.Jpeg);
}

The calls to Draw.... you can draw primitives, images, text and so forth.

Also remember that is text looks jagged, you have methods on the Graphics object to smooth this out. In this case g.TextRenderingHint = TextRenderingHint.AntiAlias;

There are also other options to make it look better, if you feel it is jagged. The default settings is geared more towards performance than quality, so if you want high quality you need to set this yourself. g.SmoothingMode set to for example HighQuality will make your round primitives look much smoother than the default configuration.

It's really easy to use, and to make the final image look like you want it to, so give it a try!

Øyvind Bråthen
if things look blocky, set a higher quality on the jpeg saving
Will
A: 

GDI+ and the System.Drawing namespace are what is required to do what you want. A basic example is below but there are many resources on the net detailing more advanced features:

using(Bitmap myBitmap = new Bitmap("C:\\backgroundImage.jpg"))
using(Graphics g = Graphics.FromImage(myBitmap))
{
   g.DrawString("Text", new Font("Arial", 10), Brushes.White, new PointF(0, 0));
   myBitmap.Save("C:\\newImage.jpg");
}
Andy Rose
You should always dispose the GDI+ objects, for example by using the "using" structure. Failure to do so may lead to stalls.
Skrim
-1: This adds nothing to my answer that was posted several minutes earlier, and in addition omits the disposing of GDI+ objects that are vital as Skrim also have commented.
Øyvind Bråthen
@Øyvind when you initially posted your answer you did not include anything regarding adding text which was specified i the question. Why so mean?
Andy Rose
@Skrim good point, I have added the necessary Dispose calls to make this obvious.
Andy Rose
@Andy: There is still a problem doing it like this. If for example myBitmap.Save throws an exception, your Dispose statements will never be run. You should either use Using blocks for them, or put them into a try/finally block.
Øyvind Bråthen
@Andy: I'm not trying to be mean. I just feel that the post does not add anything useful, and also lack the necessary Dispose functionality, so therefore I think the downvote was deserved.
Øyvind Bråthen
@Øyvind Bråthen - but the question specifically asked about creating an image from another image and adding text which your answer, in it's original form before you edited it, did not cover.
Andy Rose
+4  A: 

in .Net 3.5/4 you can also use WPF/Media.Imaging as an alternative to GDI+

First create a DrawingVisual and a DrawingContext:

DrawingVisual visual = new DrawingVisual();
DrawingContext dc = visual.RenderOpen();

Then draw stuff on it:

dc.DrawRectangle(...);
dc.DrawText(...);
etc...

Make sure you close it:

 dc.Close();

The great thing about WPF is everything in the GUI is actually a visual too, so if you prefer you don't have to use the code above to draw programatically, you can actually build up your visual in xaml on a window and then just render that straight to the RenderTargetBitmap.

Once you have built your visual you can render it to a file using an encoder (.Net has encoders for Jpeg, Png, Bmp, Gif, Tiff and Wmp).

// Create a render target to render your visual onto. The '96' values are the dpi's, you can set this as required.
RenderTargetBitmap frame = new RenderTargetBitmap((int)visual.ContentBounds.Width, (int)visual.ContentBounds.Height, 96, 96, PixelFormats.Pbgra32);
frame.Render(visual);

// Now encode the rendered target into Jpeg and output to a file.
JpegBitmapEncoder jpeg = new JpegBitmapEncoder();
jpeg.Frames.Add(BitmapFrame.Create(frame));
using (Stream fs = File.Create(@"c:\filename.jpg"))
{
    jpeg.Save(fs);
}

There are some good MS Tutorials on Drawing Objects and WPF Graphics Rendering.

Simon P Stevens
A: 

Instead of good old GDI+ you can use the more modern (and often faster) System.Windows.Media.Imaging APIs.

bitbonk