I currently have an image which gets displayed to the user, I'm trying to add dynamic text to this image based on two parameters passed in.
The issue I have is when I step through the code it all seems to be working correctly, however when I see the image on the screen after the below code has run it doesn't have the text on it.
Below is my current set up of code:
public ActionResult GenerateImage(string savingAmount, string savingDest)
{
// Hardcoding values for testing purposes.
savingAmount = "25,000.00";
savingDest = "Canada";
PointF firstLocation = new PointF(10f, 10f);
PointF secondLocation = new PointF(10f, 50f);
Image imgBackground = Image.FromFile(Server.MapPath("~/assets/img/fb-share.jpg"));
int phWidth = imgBackground.Width; int phHeight = imgBackground.Height;
Bitmap bmBackground = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
bmBackground.SetResolution(72, 72);
Graphics grBackground = Graphics.FromImage(bmBackground);
Bitmap bmWatermark;
Graphics grWatermark;
bmWatermark = new Bitmap(bmBackground);
bmWatermark.SetResolution(imgBackground.HorizontalResolution, imgBackground.VerticalResolution);
grWatermark = Graphics.FromImage(bmWatermark);
grBackground.SmoothingMode = SmoothingMode.AntiAlias;
// Now add the dynamic text to image
using (Graphics graphics = Graphics.FromImage(imgBackground))
{
using (Font arialFont = new Font("Arial", 10))
{
grWatermark.DrawString(savingAmount, arialFont, Brushes.White, firstLocation);
grWatermark.DrawString(savingDest, arialFont, Brushes.White, secondLocation);
}
}
imgBackground.Save(Response.OutputStream, ImageFormat.Png);
Response.ContentType = "image/png";
Response.Flush();
Response.End();
return null;
}
As mentioned after this code has run, I then see the image in the browser however text is not displayed on the image, can anyone see / suggest what maybe causing this issue?
I feel like there are way to many images in that code for what you are describing as the intent of the code. What you want should reduce to this:
Load Image
Create Graphics on that Image
Draw into the Graphics and close
Output image to client
In the code sample you provided you are opening the Graphics on imgBackground then drawing into the grWatermark graphics which is opened earlier on against an image you never touch again.
public ActionResult GenerateImage(string savingAmount, string savingDest)
{
// Hardcoding values for testing purposes.
savingAmount = "25,000.00";
savingDest = "Canada";
PointF firstLocation = new PointF(10f, 10f);
PointF secondLocation = new PointF(10f, 50f);
Image imgBackground = Image.FromFile(Server.MapPath("~/assets/img/fb-share.jpg"));
using (Graphics graphics = Graphics.FromImage(imgBackground))
{
using (Font arialFont = new Font("Arial", 10))
{
graphics.DrawString(savingAmount, arialFont, Brushes.White, firstLocation);
graphics.DrawString(savingDest, arialFont, Brushes.White, secondLocation);
}
}
imgBackground.Save(Response.OutputStream, ImageFormat.Png);
Response.ContentType = "image/png";
Response.Flush();
Response.End();
return null;
}
Related
Going through the steps mentioned here
and using IDAutomationCode39, I am getting the barcode image, however they are very blurr and only scans bigger size images. My barcode id will be upto 30 characters long, which is causing a very wide barcode image. Where could the problem lie? Is it the IDAutomationCode39 or my setting in my button click event below?
private void button1_Click(object sender, EventArgs e)
{
string abbre = GenerateProdCodeFromProductName();
txt2.Text = abbre;
string barcode = txt1.Text;
Bitmap bitm = new Bitmap(barcode.Length * 45, 160);
bitm.SetResolution(240, 240);
using (Graphics graphic = Graphics.FromImage(bitm))
{
Font newfont = new Font("IDAutomationHC39M", 6);
PointF point = new PointF(5f, 5f);
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
graphic.FillRectangle(white, 0, 0, bitm.Width, bitm.Height);
graphic.DrawString("*" + barcode + "*", newfont, black, point);
}
using (MemoryStream Mmst = new MemoryStream())
{
bitm.Save("ms", ImageFormat.Jpeg);
pictureBox1.Image = bitm;
pictureBox1.Width = bitm.Width;
pictureBox1.Height = bitm.Height;
}
}
Thank you.
I don't see any PlugIn reference in your code, you are just using a Code39 ASCII font to print a Barcode on a Bitmap.
The problem I see is that the size of the resulting Bitmap is unscaled.
What I mean is, you let the size of the Barcode determine the size of the final graphic image.
It is usually the opposite. You have some defined dimensions for a Bitmap, because of layout constraints: you have to print the barcode to a label, for example.
If the generated Barcode is wider than its container, you have to normalize it (scale it to fit).
Here is what I propose. The size of the Bitmap if fixed (300, 150). When the Barcode is generated, its size is scaled to fit the Bitmap size.
The quality of the image is preserved, using an Bicubic Interpolation in case of down scaling. The resulting graphics is also Anti-Aliased.
(Anti-Alias has a good visual render. May not be the best choice for printing. It also depends on the printer.)
The generated Bitmap is then passed to a PictureBox for visualization and saved to disk as a PNG image (this format because of its loss-less compression).
Here is the result:
string Barcode = "*8457QK3P9*";
using (Bitmap bitmap = new Bitmap(300, 150))
{
bitmap.SetResolution(240, 240);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
Font font = new Font("IDAutomationSHC39M", 10, FontStyle.Regular, GraphicsUnit.Point);
graphics.Clear(Color.White);
StringFormat stringformat = new StringFormat(StringFormatFlags.NoWrap);
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
graphics.TextContrast = 10;
PointF TextPosition = new PointF(10F, 10F);
SizeF TextSize = graphics.MeasureString(Barcode, font, TextPosition, stringformat);
if (TextSize.Width > bitmap.Width)
{
float ScaleFactor = (bitmap.Width - (TextPosition.X / 2)) / TextSize.Width;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.ScaleTransform(ScaleFactor, ScaleFactor);
}
graphics.DrawString(Barcode, font, new SolidBrush(Color.Black), TextPosition, StringFormat.GenericTypographic);
bitmap.Save(#"[SomePath]\[SomeName].png", ImageFormat.Png);
this.pictureBox1.Image = (Bitmap)bitmap.Clone();
font.Dispose();
}
}
In that image particular height weight text need to be extract text. For that i used modiDocument. codes re below:
public string ExtractTextFromImage(string filepath)
{
try
{
Document modiDocument = new Document();
modiDocument.Create(filepath);
modiDocument.OCR(MiLANGUAGES.miLANG_ENGLISH);
MODI.Image modiImage = (modiDocument.Images[0] as MODI.Image);
string extractedText = modiImage.Layout.Text;
modiDocument.Close();
return extractedText;
}
catch (Exception)
{
throw;
}
return filepath;
}
From above code i can get fill text from image. how to take particular height width text from image.
Quote from https://stackoverflow.com/a/734941/3966756
You can use Graphics.DrawImage to draw a cropped image onto the graphics object from a bitmap.
Rectangle cropRect = new Rectangle(...);
Bitmap src = Image.FromFile(fileName) as Bitmap;
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
using(Graphics g = Graphics.FromImage(target))
{
g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height),
cropRect,
GraphicsUnit.Pixel);
}
Quote end
Using this Code for cropping the image you can only load the part of the Image you want to extract the text from.
Since i don't know if MODIDocuments support loading from a bitmap instead of a file you may need to write a temporary file somwhereon your filesystem.
I am currently making an MVC project where the User will receive a Certificate which is displayed on the page. The Certificate is an image and then Text is used to overlap the image where the Users name and other information will be printed, using css to format the text to the correct part of the image.
As the image and text are technically still separate, saving the image does not save the text on top so what you save is just the template of a certificate and no text.
Is there a way to save both image and text as one, as if the text was pressed onto the image and was the same object? If so, I would appreciate being pointed in the right direction to know how to do this. Any ideas or code to save an image and text as one it would be very helpful.
Thanks.
May this help you
private void makeCertificate(string name, string id, string otherDetails) //You can pass any other details as well
{
System.Drawing.Image PrePrintedCertificate;
name = name.ToUpper();
string PrePrintedCertificateName = "Certificate.jpg"; //Assuming Certificate JPG File is in the bin folder
using (FileStream stream = new FileStream(PrePrintedCertificateName, FileMode.Open, FileAccess.Read))
{
PrePrintedCertificate = System.Drawing.Image.FromStream(stream);
}
RectangleF rectf4Name = new RectangleF(655, 460, 535, 90); //rectf for Name
RectangleF rectf4ID = new RectangleF(655, 560, 400, 40);
System.Drawing.Rectangle rect;
Bitmap picEdit = new Bitmap(PrePrintedCertificate, new System.Drawing.Size(1241, 1756));
using (Graphics g = Graphics.FromImage(picEdit))
{
//g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Color.Red, 2), 662, 530, 90, 40);
//I have used upper line to see where is my RectangleF creating on the image
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
StringFormat sf1 = new StringFormat();
sf1.Alignment = StringAlignment.Near;
//g.DrawImage(codeImage, rect); //If you wanted to draw another image on the certificate image
g.DrawString(name, new System.Drawing.Font("Thaoma", 26, System.Drawing.FontStyle.Bold), System.Drawing.Brushes.Black, rectf4Name, sf);
g.DrawString(Track.Text, new System.Drawing.Font("Thaoma", 14, System.Drawing.FontStyle.Bold), System.Drawing.Brushes.Black, rectf4ID, sf1);
}
try
{
if (File.Exists(id + ".jpg"))
File.Delete(id + ".jpg");
picEdit.Save(id + ".jpg", ImageFormat.Jpeg);
picEdit.Dispose();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Things to note here is that this image is a A4 size paper image with portrait orientation. You probably need to change Bitmap picEdit = new Bitmap(PrePrintedCertificate, new System.Drawing.Size(1241, 1756)); to Bitmap picEdit = new Bitmap(PrePrintedCertificate, new System.Drawing.Size(1756,1241));
Another thing is the names and other details has been printed on the image with random place but you can see where exactly you wish to print the details.
You can look where it will get printed using g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Color.Red, 2), 662, 530, 90, 40); the Parameters you gonna pass here will be same as the RectangleF Parameters.
Save the graphic as an SVG and add the text using a text object.
You can also use CSS within the SVG to style the text.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text x="20" y="40">Example SVG text 1</text>
</svg>
I have worked on image capture window application. When I have captured image by application in window tablet then image quality low and show darkness in captured image background. When I have captured image by tablet then image is good quality.
What is missing/problem in my code?
I have used code share by you...
private void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone();
ImgContainer.Image = b;
}
private void btnKeep_Click(object sender, EventArgs e)
{
int width = 457;
int height = 350;
Image tmpimg = ImgContainer.Image;
System.Drawing.Bitmap b = new System.Drawing.Bitmap(ImgContainer.Image, width, height);
System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(b);
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, width, height);
System.Drawing.Imaging.ImageCodecInfo codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[1];
System.Drawing.Imaging.EncoderParameters eParams = new System.Drawing.Imaging.EncoderParameters(1);
eParams.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
string ImagePath = Guid.NewGuid().ToString();
string imagefullpath = System.AppDomain.CurrentDomain.BaseDirectory + "imageFolder\\" + ImagePath + ".jpg";
b.Save(imagefullpath);
}
Show you captured by application image ............
Show you captured by tablet ............
Please give me any idea and solution remove darkness captured by application (above image).
You can use a DrawImage with an ImageAttributes instance to change the gamma. I found 0.5f to work:
Here is a function that applies a gamma value to a bitmap and returns a modified bitmap. It is up to you to ..:
make sure you don't leak resources
make sure to apply the gamma always to the original and not repeatedly to the same bitmap when giving the user a trackbar to find a good value..
The function:
public static Bitmap ApplyGamma(Bitmap bmp0, float gamma)
{
Bitmap bmp1 = new Bitmap(bmp0.Width, bmp0.Height);
using (Graphics g = Graphics.FromImage(bmp1))
{
ImageAttributes attributes = new ImageAttributes();
attributes.SetGamma(gamma, ColorAdjustType.Bitmap);
g.DrawImage(bmp0, new Rectangle(0, 0, bmp0.Width, bmp0.Height),
0, 0, bmp0.Width, bmp0.Height, GraphicsUnit.Pixel, attributes);
}
return bmp1;
}
The calling code I used:
Image img = Image.FromFile(yourImage); // some image to use
float gamma = (float)(trackBar1.Value / 10f); // a trackbar to test
Text = "Gamma = " + gamma; // a control display
pictureBox1.Image = ApplyGamma((Bitmap)img, gamma);
If you also want to change contrast and/or brightness you can use a ColorMatrix. See here for an example!
I'm trying to add some text to an Image programmatically and later I save it. But the end result is somewhat not convincing.
The text on the image appears quite blurry.
The snippet I use to render is as follows :
static void ModifyImage()
{
Image origImage;
if (File.Exists(path))
{
using (Stream s = new FileStream(path, FileMode.Open, FileAccess.Read))
{
origImage = Image.FromStream(s);
}
using (Image newImage = new Bitmap(path))
{
// Get the image's original width and height
int originalWidth = origImage.Width;
int originalHeight = origImage.Height;
// To preserve the aspect ratio
float ratio = Math.Min((float)originalWidth, (float)originalHeight);
Graphics graphics = Graphics.FromImage(newImage);
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
string strSoftwareVersion = "Version " + StrVersion;
var oVersionFont = new Font("Arial", 15f, FontStyle.Bold);
SizeF strSize = graphics.MeasureString(strSoftwareVersion, oVersionFont);
float mX = (float)((originalWidth * 0.85) - 5.0);
float mY = (float)((originalHeight * 0.85) - 5.0);
float mWidth = (float) (strSize.Width + 5.0);
float mHeight = (float)(strSize.Height + 10.0);
/*
* Alternate I tried.
*/
//GraphicsPath blackfont = new GraphicsPath();
//SolidBrush brsh = new SolidBrush(Color.White);
//blackfont.AddString("TEST APP", oVersionFont.FontFamily, (int)FontStyle.Bold, 15, new Point((int)(originalWidth * 0.85), (int)(originalHeight * 0.85)), StringFormat.GenericDefault);
//graphics.FillPath(brsh, blackfont);
/*
*Software Version String
*/
graphics.DrawString("Version " + StrVersion, new Font("Arial", 15f, FontStyle.Bold), Brushes.White, (int)(originalWidth * 0.85), (int)(originalHeight * 0.85));
/*
* Save processed image
*/
newImage.Save(newPath, ImageFormat.Jpeg);
}
origImage.Dispose();
}
}
As you can see from the image, the blurriness of the text and surrounding areas are quite prominent. I'm quite sure this is due to the Aliasing or TextRendering issue with the alpha levels, but just not able to point the exact issue.
The text looks fine to me.
To make it crispier you can turn off all antialiasing.
The 'surrounding areas' obviously show some jpeg artifacts.
Good text and jpeg don't go together well.
Either turn up jpeg quality settings up from the default (of around 75%) or go for png!
Note that 90-95% quality, while greatly improving text quality also greatly enlarges size and going for png may well save you space in addition to being lossless..
I had a similar issue with the text being quite badly aliased when drawn onto the image. This is my solution which produces a reasonable text quality.
"text" is a System.Windows.Media.FormattedText instance.
BitmapFrame originalImageSource = BitmapFrame.Create(new Uri(file.FullName), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
var visual = new DrawingVisual();
using(DrawingContext drawingContext = visual.RenderOpen()) {
drawingContext.DrawImage(originalImageSource, new Rect(0, 0, originalImageSource.PixelWidth, originalImageSource.PixelHeight));
drawingContext.DrawText(text, topRight);
}
var renderTargetBitmap = new RenderTargetBitmap(originalImageSource.PixelWidth,
originalImageSource.PixelHeight,
originalImageSource.DpiX, originalImageSource.DpiY,
PixelFormats.Pbgra32);
renderTargetBitmap.Render(visual);
BitmapFrame bitmapFrame = BitmapFrame.Create(renderTargetBitmap);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(bitmapFrame);
encoder.Save(stream);