locked
Magic Formula: text on image RRS feed

  • Question

  • User-283860200 posted

    Hi all,

    I have played around with many settings for writing text onto jpg image files. I've read the quantize stuff and have the typical settings in place.
    I've tried all the text rendering hints (see code). I have found that different colors of the same font, yield varying results in quality after the text is written onto the image.

    I have read a lot of great stuff here and elsewhere on the web, but not everything works well in all situations.

    Is there some BEST font to use which most often yields crisp results in any color?  Does it depend on the pixels below the text in the image?
    Would it be better to create a transparent GIF of the text and place that on the jpg instead of writing the text directly?  Should the resolutions of each of these images be the same for best quality results?  Is there a better brush setting to use?  This code allows user to select color from a dropdown on the form before processing (ddlBrandTextColor.SelectedValue).

    some code...
    If frmBrand.Text.Trim.Length > 0 Then
            pics = Directory.GetFiles(cpdir, "*.jpg")
            Dim cpudir As String = "c:\inetpub\websites\sitename\subdir\" + frmEventFolderName.Text.Trim
            Dim myBrush As Brush = New SolidBrush(Color.FromName(ddlBrandTextColor.SelectedValue))
            For i = 0 To picCount - 1
               Dim FileToDrawTextOn As String = pics(i)
               Dim originalBitmap As New Bitmap(FileToDrawTextOn)

               Dim font As System.Drawing.Font = New Font("Arial", 12, FontStyle.Regular)

               Dim g As Graphics = Graphics.FromImage(originalBitmap)
               g.DrawImage(originalBitmap, 640, 480)

               g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
               g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
               g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
               g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality

               'Other types of rendering hints that are of lower quality
               'g.TextRenderingHint = TextRenderingHint.AntiAlias
               'g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit
               'g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit
               g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit


               g.DrawString(frmBrand.Text.Trim, font, myBrush, 10.0F, 10.0F)


               g.Save()

               nfcpn = cpudir + "\" + "cpb_" + Right(pics(i), 11)
               originalBitmap.Save(nfcpn, System.Drawing.Imaging.ImageFormat.Jpeg)
               g.Dispose()
               originalBitmap.Dispose()
               File.Delete(pics(i))
               File.Move(nfcpn, pics(i))
           Next

     End If

    Thanks in advance if you can offer some advice. 

    Stewart

    Friday, November 3, 2006 4:42 PM

Answers

  • User247697164 posted

    Here is something I found that helped me and maybe it will help you, too.  I found that, when using text, no image formatting would work except PNG.  Everything else rendered fuzzy text.  It didn't matter if I saved at a high quality JPG; I never got reliable text.  When I started saving in PNG format (even if the image had the JPG extension), it worked perfectly.  So modify your save line to something like this:

    originalBitmap.Save(nfcpn, System.Drawing.Imaging.ImageFormat.Png)

    And see if that makes a difference.

    -Jacob

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 17, 2006 2:20 PM
  • User247697164 posted

    Yea, I'm not crazy about the white box either.  I think your idea of making your image slightly bigger would be much better.  Like say add an extra 25-50 pixels at the bottom of the page and use that as your copyright area (or whatever you are trying to write there).  Maybe make the box black and the text white or something like that.

    Good luck!

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 21, 2006 8:56 AM
  • User247697164 posted

    Stewart-

     I just ran across something else that might be worth looking at.  I was playing around with another text issue and started playing around with creating a GraphicsPath for the text you want to write and then filling it in.  I was playing with it in JPG format and it came out pretty clear.  If you are still wanting to experiment, you might want to look into that.  It seemed like a much better solution than just writing out the text onto the image IMHO.

    -Jacob

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 28, 2006 11:03 AM
  • User247697164 posted

    That's crazy.  Interesting but crazy.  Did you read the link at the bottom, too?

    Even if this works out for you, I am not sure you won't take a performance hit, even over the PNG.  You are having to rotate the image 90 degrees, save it to your hard drive and delete the original file.  Then open up the rotated image, rotate it back to the normal orientation, I guess add text at this point, then save it back to the original file and deleting the temporary file.  So you are saving the image to your hard drive twice. 

    Of course, the end result will be much nicer to your harddrive size-wise, but still, that seems like potentially a lot of time.

    I wonder if it works.  If I have time to play around with it, I will.  I really want to know.  If you test it out, post what you find.  I'll do the same.

    Thanks!

    -Jacob

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 5, 2006 1:56 PM

All replies

  • User-283860200 posted

    Maybe asking this way will generate some ideas.

    In this code below, "g.DrawString(frmBrand.Text.Trim, font, Brushes.White, 3, 40)" produces nice white text on the image.
    However, using "g.DrawString(frmBrand.Text.Trim, font, Brushes.Red, 3, 40)" looks horrible on the same image.

    Why?  Is it the interaction of the drawn text pixels over the underlying jpg image pixels that causes this? 

    Is it generally better to perhaps create a rectangle with transparent canvas, place my text in it of desired color and then place this image
    over the underlying pic (versus the drawing text method)?

    If frmBrand.Text.Trim.Length > 0 Then
            pics = Directory.GetFiles(cpdir, "*.jpg")
            Dim cpudir As String = "c:\inetpub\websites\sitename\subdir\" + frmEventFolderName.Text.Trim
            Dim myBrush As Brush = New SolidBrush(Color.FromName(ddlBrandTextColor.SelectedValue))
            For i = 0 To picCount - 1
               Dim FileToDrawTextOn As String = pics(i)
               Dim originalBitmap As New Bitmap(FileToDrawTextOn)

               Dim font As System.Drawing.Font = New Font("Arial", 12, FontStyle.Regular)

               Dim g As Graphics = Graphics.FromImage(originalBitmap)
               g.DrawImage(originalBitmap, 640, 480)

               g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
               g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
               g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
               g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality

               g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit
               g.DrawString(frmBrand.Text.Trim, font, Brushes.White, 3, 40)

               g.Save()

               nfcpn = cpudir + "\" + "cpb_" + Right(pics(i), 11)
               originalBitmap.Save(nfcpn, System.Drawing.Imaging.ImageFormat.Jpeg)
               g.Dispose()
               originalBitmap.Dispose()
               File.Delete(pics(i))
               File.Move(nfcpn, pics(i))
           Next

     End If

     

    Thursday, November 9, 2006 12:17 AM
  • User-283860200 posted

    Perhaps someone could address this specifically...

    I have a jpg image which has a pixelformat of Format24bppRgb.

    Is there a "best" way to write text onto this image so that no matter what font or color is selected, the text quality is good?

    Using this line of code, the white text looks great. 
    g.DrawString(frmBrand.Text.Trim, font, Brushes.White, 3, 40)

    Using this line of code, the red text looks bad.
    g.DrawString(frmBrand.Text.Trim, font, Brushes.Red, 3, 40)

    I tried arial 12 bold and regular and verdana 12 bold and regular.  The issue is present regardless.

    The red pixels inside the boundaries of each letter don't appear filled consistently.  What I mean is that I don't have a nice even fill of red inside the letter.  Some pixels appear darker (in color?) or weaker (in alpha?) than others. ALSO... there is a small spattering of red pixels outside the letters.
    These are noticeable. 

    I don't get seem to get the spattering with white.  The pixels of the image on which this text is placed is a blue sky (from a digital photograph).
    The blue sky pixels are consistently similar (no intervening clouds or noticeable differences in light).

    Any thoughts?

    Thanks,

    Stewart

    Friday, November 10, 2006 12:58 AM
  • User247697164 posted

    Here is something I found that helped me and maybe it will help you, too.  I found that, when using text, no image formatting would work except PNG.  Everything else rendered fuzzy text.  It didn't matter if I saved at a high quality JPG; I never got reliable text.  When I started saving in PNG format (even if the image had the JPG extension), it worked perfectly.  So modify your save line to something like this:

    originalBitmap.Save(nfcpn, System.Drawing.Imaging.ImageFormat.Png)

    And see if that makes a difference.

    -Jacob

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 17, 2006 2:20 PM
  • User-283860200 posted

    Hi Jacob,

    Thanks for the tip. It worked like a a charm! File size is approx 10X larger, but quality is superb.  Fortunately, this app only shows one image on a page, so page rendering time is acceptable.

    Have you ever played with Drawing2D.CompositingMode.SourceCopy ??

    I was trying tio utilize it to force the red brushed text pixels to overwrite whatever background pixels were present.  It didn't work as I expected.
    I'm not even sure it works when you fire a dxrawstring.

    Thanks!

    Stewart

    Friday, November 17, 2006 8:44 PM
  • User-283860200 posted

    Jacob,

    With respect to this article, http://www.bobpowell.net/modifyImage.htm and specifically this image, http://www.bobpowell.net/testimage.jpg, I found that I attained good quality text (in red, blue or whatever color) when I had the drawstring write inside the rectangular region that was drawn on the bitmap instance of my jpg file.  The resultant jpg file size was very close to the original jpg.

    I'm just not crazy about the white fill/bg of the rectangle.  A transparent fill would be cool, but then we're back to PNG.

    I also thought about attaching the rectangle outside an existing edge of the jpg, so as to not overwrite, but essentially making the image slightly larger.  I guess I could resize it back down to original size and perhaps wouldn't get bad quality text since its still on the white rectangle area.

    BTW, Kudos and Thanks to Bob's excellent articles and FAQ! 

    Regards,
    Stewart

     

    Saturday, November 18, 2006 1:23 AM
  • User247697164 posted

    Yea, I'm not crazy about the white box either.  I think your idea of making your image slightly bigger would be much better.  Like say add an extra 25-50 pixels at the bottom of the page and use that as your copyright area (or whatever you are trying to write there).  Maybe make the box black and the text white or something like that.

    Good luck!

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 21, 2006 8:56 AM
  • User247697164 posted

    Stewart-

     I just ran across something else that might be worth looking at.  I was playing around with another text issue and started playing around with creating a GraphicsPath for the text you want to write and then filling it in.  I was playing with it in JPG format and it came out pretty clear.  If you are still wanting to experiment, you might want to look into that.  It seemed like a much better solution than just writing out the text onto the image IMHO.

    -Jacob

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 28, 2006 11:03 AM
  • User-283860200 posted

    Jacob,

    Just before I came here to see your reply, I was in the other thread, http://forums.asp.net/thread/1478156.aspx, noted the technique
    and am going to try it.  I'll write back later with results/findings.

    Thanks for the advice!

    Stewart

    Thursday, November 30, 2006 1:48 AM
  • User-283860200 posted

    Hi Jacob,

    I tried the technique using this code snip:

    ... other preceding code ...

    Dim fontpath As New GraphicsPath
    fontpath.AddString("My Test", New FontFamily("Verdana"), FontStyle.Regular, 16, New Point(3, 200), StringFormat.GenericDefault)
    g.FillPath(Brushes.Red, fontpath)

    'g.DrawPath(New Pen(Color.Red, 1), fontpath) <<< tried with and without since I wasn't after outlining  - just the fillpath VS drawstring results

    g.Save()
    originalBitmap.Save(cpudir + "\" + "pic-001Text.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
    fontpath.Dispose()
    g.Dispose()
    originalBitmap.Dispose()

    With the Jpeg format, it came out poor. 

    So, far the best results are with using Png and living with the increased file size OR using the fudge techniques we discussed:
    a) attaching a rectangular white gb border to one side, writing text inside and keeping jpeg format
    b) drawing a white bg rectangle on the image and writing the text inside the rectangle and keeping jpeg format

    Two Queries I'm still pondering:
    1) Do you think there's a difference in output when framework 1.1 is used VS 2.0?  Could the routines be "better" in 2.0 for these functions?
    I have never looked up whether certain classes/methods that exist in both have been enhanced (in terms of output quality in thise case) in 2.0 over 1.1

    2) Still wondering about the compositing thingie in my other post.  The sourcecopy is supposed to guarantee overwrite, not blending.  At a glance, it seems like this should be able to be tapped in some way - maybe not with drawstring but perhaps with the fillpath.

    Still working on it....

    Regards,
    Stewart

    Friday, December 1, 2006 12:57 AM
  • User-283860200 posted

    Jacob,

    Have you seen this article or heard of this technique to prevent loss in jpeg when saving?
    This example addresses writing info into the EXIF data but addresses loss while doing this
    unless image is rotated.  Then they rotate it back.

    I haven't tried it yet with drawstring.

    Stew

     

    Tuesday, December 5, 2006 3:34 AM
  • User-283860200 posted
    Oops... URL for the above is: http://www.eggheadcafe.com/articles/20030706.asp
    Tuesday, December 5, 2006 3:35 AM
  • User247697164 posted

    That's crazy.  Interesting but crazy.  Did you read the link at the bottom, too?

    Even if this works out for you, I am not sure you won't take a performance hit, even over the PNG.  You are having to rotate the image 90 degrees, save it to your hard drive and delete the original file.  Then open up the rotated image, rotate it back to the normal orientation, I guess add text at this point, then save it back to the original file and deleting the temporary file.  So you are saving the image to your hard drive twice. 

    Of course, the end result will be much nicer to your harddrive size-wise, but still, that seems like potentially a lot of time.

    I wonder if it works.  If I have time to play around with it, I will.  I really want to know.  If you test it out, post what you find.  I'll do the same.

    Thanks!

    -Jacob

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, December 5, 2006 1:56 PM
  • User-239834356 posted

    very good , look like a magic, thanks png format you  share

    Tuesday, November 3, 2009 12:13 AM