itextsharp: forcing image to take up entire width in vb.net - vb.net

the following is a generated PDF with a few images. how do i force the image to take up the entire width of the pdf file?
alt text http://img52.imageshack.us/img52/3324/fullscreencapture121420u.png

The ScalePercent method works pretty well for this.
Dim pgSize As New iTextSharp.text.Rectangle(595, 792) //A4 width, Letter height
Dim leftMargin as integer = 20
Dim rightMargin as integer = 20
Dim doc As New iTextSharp.text.Document(pgSize, leftMargin, rightMargin, 48, 24)
//Create PDF and write other stuff.
Dim img As System.Drawing.Image = My.Resources.My_Image
Dim png As System.Drawing.Imaging.ImageFormat = System.Drawing.Imaging.ImageFormat.Png
Dim pic1 As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(img, png)
Dim scaleFactor As Single = (pgSize.Width - leftMargin - rightMargin) / img.Width * 100
pic1.ScalePercent(scaleFactor)
pic1.SetAbsolutePosition(my_X, my_Y)
doc.Add(pic1)

Related

VB.net crop an image (jpg) like ms paint with no quality loss

Given an jpg image slightly larger than 19" x 23" I need to crop it to exactly 19" x 23" and preserve the original quality using VB.NET.
I can do this in MS paint, If I open a 2851 x 4651 200 DPI jpg and use the Image Properties dialog I can change the width and Height to 3800 x 4600 (exactly 19" x 23" # 200 DPI).
The resultant image is identical to the original in quality and compression but is cropped on the right and bottom by the 51 pixels. The file size is slightly smaller as expected.
When I use the many techniques I have found on SO to crop/resize an image when I save the image it always saves as 96 DPI. I can adjust the width and height to accommodate the 96 DPI so the end result is exactly 19" x 23", however the resulting pixilation is higher than the original, and the files size is considerably smaller, so obvious quality loss.
What I want is to do is (a simple?) crop like MS paint does. Just take a little off the side and bottom, but I cannot seem to save an image with anything other than 96 DPI.
If I can figure out how to the save the cropped file at 200 DPI (or whatever the original image was) I think what I have will work fine.
I am willing to use an external library if that is what it takes.
Here is one example that works in the sense that the resulting image is 19" x 23" and the image is actually scaled preserving the aspect ratio, however the quality is less than the original.
This code is from another SO answer with some minor modifications.
Public Shared Function ResizeImage(SourceImage As Drawing.Image, TargetWidthIn As Decimal, TargetHeightIn As Decimal) As Drawing.Bitmap
'Dim TargetWidth As Integer = TargetWidthIn * SourceImage.HorizontalResolution
'Dim TargetHeight As Integer = TargetHeightIn * SourceImage.VerticalResolution
Dim TargetWidth As Integer = TargetWidthIn * 96
Dim TargetHeight As Integer = TargetHeightIn * 96
Dim bmSource = New Drawing.Bitmap(SourceImage)
Dim bmDest As New Drawing.Bitmap(TargetWidth, TargetHeight, Drawing.Imaging.PixelFormat.Format32bppArgb)
Dim nSourceAspectRatio = bmSource.Width / bmSource.Height
Dim nDestAspectRatio = bmDest.Width / bmDest.Height
Dim NewX = 0
Dim NewY = 0
Dim NewWidth = bmDest.Width
Dim NewHeight = bmDest.Height
If nDestAspectRatio = nSourceAspectRatio Then
'same ratio
ElseIf nDestAspectRatio > nSourceAspectRatio Then
'Source is taller
NewWidth = Convert.ToInt32(Math.Floor(nSourceAspectRatio * NewHeight))
NewX = Convert.ToInt32(Math.Floor((bmDest.Width - NewWidth) / 2))
Else
'Source is wider
NewHeight = Convert.ToInt32(Math.Floor((1 / nSourceAspectRatio) * NewWidth))
NewY = Convert.ToInt32(Math.Floor((bmDest.Height - NewHeight) / 2))
End If
Using grDest = Drawing.Graphics.FromImage(bmDest)
With grDest
.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
'.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
.InterpolationMode = Drawing.Drawing2D.InterpolationMode.NearestNeighbor
.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
.CompositingMode = Drawing.Drawing2D.CompositingMode.SourceCopy
'.SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias
'.CompositingMode = Drawing.Drawing2D.CompositingMode.SourceOver
.DrawImage(bmSource, NewX, NewY, NewWidth, NewHeight)
End With
End Using
Return bmDest
End Function
I found a solution on SO here
I modifyed my original code above to keep the DPI of the original image:
Dim TargetWidth As Integer = TargetWidthIn * SourceImage.HorizontalResolution
Dim TargetHeight As Integer = TargetHeightIn * SourceImage.VerticalResolution
Then after the call to ResizeImage:
Select Case imageType.ToLower
Case "jpg"
Dim jpgEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
Dim myEncoder As System.Drawing.Imaging.Encoder = System.Drawing.Imaging.Encoder.Quality
Dim myEncoderParams As New EncoderParameters(1)
Dim myEncoderQuality As New EncoderParameter(myEncoder, CType(98L, Int32)) '98%
myEncoderParams.Param(0) = myEncoderQuality
bm.SetResolution(img.HorizontalResolution, img.VerticalResolution)
bm.Save(tempfile, jpgEncoder, myEncoderParams)
Case "png", "gif"
bm.Save(tempfile, System.Drawing.Imaging.ImageFormat.Png)
Case "tiff", "tif"
bm.Save(tempfile, System.Drawing.Imaging.ImageFormat.Tiff)
Case Else
bm.Save(tempfile, System.Drawing.Imaging.ImageFormat.Png)
End Select
bm.Dispose()
I only use jpg now so I don't know if the tiff and png parts work, but it seems using the jpeg encoder allowed me to save the file with 200 DPI and maintain the original quality.
Here is the GetEncoder part that is missing from the other post:
Private Shared Function GetEncoder(f As Drawing.Imaging.ImageFormat) As ImageCodecInfo
Dim myEncoders() As ImageCodecInfo
myEncoders = ImageCodecInfo.GetImageEncoders()
Dim numEncoders As Integer = myEncoders.GetLength(0)
Dim strNumEncoders As String = numEncoders.ToString()
' Get the info. for all encoders in the array.
If numEncoders > 0 Then
Dim myEncoderInfo(numEncoders * 10) As String
For i As Integer = 0 To numEncoders - 1
If myEncoders(i).FilenameExtension.Contains(f.ToString.ToUpper) Then
Return myEncoders(i)
End If
Next
End If
Return Nothing

How to auto align and adjust text in VB.net that getting converted to Image

I was trying with a code that coverts Text to Image using Vb.net and my problem is I need to accept a message from user (Max 160 Characters) by a text box and i need to convert it to a Image. The generated image should be aligned in the middle and the image max resolution should be 800x600.
So the message should be neatly aligned in new lines if needed and perfectly aligned to the middle.
The code I am trying is as follows:
======================================================
Try
Dim Text As String = TextBox3.Text
Dim FontColor As Color = Color.Blue
Dim BackColor As Color = Color.White
Dim FontName As String = "Times New Roman"
Dim FontSize As Integer = 36
Dim Height As Integer = 60
Dim Width As Integer = 200
Dim daten As String
daten = Now.ToString("ddMMyyyyhhmmss")
Dim FileName As String = daten
Dim objBitmap As New Bitmap(Width, Height)
Dim objGraphics As Graphics = Graphics.FromImage(objBitmap)
Dim objColor As Color
objColor = Nothing
Dim objFont As New Font(FontName, FontSize)
'Following PointF object defines where the text will be displayed in the
'specified area of the image
Dim objPoint As New PointF(5.0F, 5.0F)
Dim objBrushForeColor As New SolidBrush(FontColor)
Dim objBrushBackColor As New SolidBrush(BackColor)
objGraphics.FillRectangle(objBrushBackColor, 0, 0, Width, Height)
objGraphics.DrawString(Text, objFont, objBrushForeColor, objPoint)
objBitmap.Save("D:\DNB\" + daten + ".JPG", ImageFormat.Jpeg)
PictureBox1.Image = Image.FromFile("D:\DNB\" + daten + ".JPG")
Catch ex As Exception
End Try
Have you tried the MeasureString function of the Graphics object and it's various overrides? With that you can measure how much space a text in a given size and font needs on the screen. With that knowledge you can calculate the upper left point to use to make the text appear centered.

Mailmerging into MS Word an image from SQLServer & resizing the image

I'm a bit new at this and I'm having problems mail merging into MS Word an image from a SQL Server table. This article.
I set a bookmark in Word as the placeholder for the image (unsure if this is best way).
Problem is the image is displaying in Word, but it is way too large.
Is there a way to resize the image before it gets to Word?
Here is my code:
Dim r As DataRow
r = dtLicence(0)
Dim MyPhoto As Object
MyPhoto = r("Photo")
myImage = MyPhoto
Dim membits As New MemoryStream(myImage)
Dim WordPhoto As Image
WordPhoto = Image.FromStream(membits)
Clipboard.SetDataObject(WordPhoto)
word_server.Selection.GoTo( _
What:=Word.WdGoToItem.wdGoToBookmark, _
Name:="Photo")
With word_server.Selection
.Paste()
End With
If anyone could provide some code sample for me to try I would appreciate it.
You could try to resize the image with this function:
WordPhoto = ScaleImage(Image.FromStream(membits), 300, 300)
And Here is the function I found:
Public Function ScaleImage(ByVal OldImage As Image, ByVal TargetHeight As Integer,_
ByVal TargetWidth As Integer) As System.Drawing.Image
Dim NewHeight As Integer = TargetHeight
Dim NewWidth As Integer = NewHeight / OldImage.Height * OldImage.Width
If NewWidth > TargetWidth Then
NewWidth = TargetWidth
NewHeight = NewWidth / OldImage.Width * OldImage.Height
End If
Return New Bitmap(OldImage, NewWidth, NewHeight)
End Function
(Source)

VB.NET - Create An Image - Resize But Add Background To Remainding Space

I am attempting to resize an image to specific dimensions but I do not want to stretch the image at all if it is smaller than my chosen dimensions. Instead I want to add a black background around the image area that is not in use.
I think that the easiest way to do this would be to create a new image of my desired dimensions & set a background color & then add & center the image over top of this background.
I have created a Bitmap using:
Dim bmp As New Drawing.Bitmap(500, 500)
Dim grap As Drawing.Graphics = Drawing.Graphics.FromImage(bmp)
grap.Clear(Drawing.Color.Black)
From this point I got a bit lost on how to complete the process, all that is needed is to add an image to the Bitmap & center.
Any ideas would be much appretiated
I haven't tested this but it looks like you've pretty much got what you want but:
grap.Clear(Drawing.Color.Black)
Will surely just wipe the entire graphic back to black.
Try doing the clear prior to drawing image:
Graphics pic = this.CreateGraphics();
pic.Clear(Color.Black);
pic.DrawImage(img, new Point(center));
Ended up using:
' Load Image
Dim FilePath As String = "testimage.jpg"
Dim OriginalImage As New Bitmap(FilePath)
' Resize Image While Maintaining Aspect Ratio
Dim aspectRatio As Double
Dim newHeight As Integer
Dim newWidth As Integer
Dim maxWidth As Integer = 500
Dim maxHeight As Integer = 500
' Calculate Size
If OriginalImage.Width > maxWidth Or OriginalImage.Height > maxHeight Then
If OriginalImage.Width >= OriginalImage.Height Then ' image is wider than tall
newWidth = maxWidth
aspectRatio = OriginalImage.Width / maxWidth
newHeight = CInt(OriginalImage.Height / aspectRatio)
Else ' image is taller than wide
newHeight = maxHeight
aspectRatio = OriginalImage.Height / maxHeight
newWidth = CInt(OriginalImage.Width / aspectRatio)
End If
Else ' if image is not larger than max then increase size
If OriginalImage.Width > OriginalImage.Height Then
newWidth = maxWidth
aspectRatio = OriginalImage.Width / maxWidth
newHeight = CInt(OriginalImage.Height / aspectRatio)
Else
newHeight = maxHeight
aspectRatio = OriginalImage.Height / maxHeight
newWidth = CInt(OriginalImage.Width / aspectRatio)
End If
' Below keeps original height & width instead of resizing to fit new height / width
' newWidth = OriginalImage.Width
' newHeight = OriginalImage.Height
End If
Dim newImg As New Bitmap(OriginalImage, CInt(newWidth), CInt(newHeight)) '' blank canvas
' Create New Bitmap
Dim bmp As New Drawing.Bitmap(500, 500)
Dim grap As Drawing.Graphics = Drawing.Graphics.FromImage(bmp)
grap.Clear(Drawing.Color.Black)
Dim g As Graphics = Graphics.FromImage(bmp)
' Calculate Points To Insert Resized Image
Dim InsertX As Integer
Dim InsertY As Integer
' Calculate Y Axis Point
If newImg.Height >= 500 Then
InsertY = 0
Else
InsertY = CInt(((500 - newImg.Height) / 2))
End If
' Calculate X Axis Point
If newImg.Width >= 500 Then
InsertX = 0
Else
InsertX = CInt(((500 - newImg.Width) / 2))
End If
' Add Resized Image To Canvas
g.DrawImage(newImg, New Point(InsertX, InsertY))
By using just the ratio of the larger axis, you can fail in the situation that the other ratio forces you to exceed the other axis.
i.e. 1400x1000 ->( i want to fit into 300x200) -> but just with 1400/300 ratio (4.6) the result will be 300x214.
I think it would be useful to check both ratios and continue with the bigger

itextsharp: how do i place an image all the way at the bottom?

i have an image that i just want to place all the way at the bottom of the page. how do i do this?
'Set these as needed
Dim DocumentWidth = 1000
Dim DocumentHeight = 1000
Dim ImagePath = "c:\test.jpg"
Dim ImageWidth As Integer
Dim ImageHeight As Integer
Using Img = System.Drawing.Image.FromFile(ImagePath)
ImageWidth = Img.Width
ImageHeight = Img.Height
End Using
'Create the document
Dim D As New Document()
'Set the page size
D.SetPageSize(New iTextSharp.text.Rectangle(0, 0, DocumentWidth, DocumentHeight))
'Zero the margins
D.SetMargins(0, 0, 0, 0)
'Create and open the PDF writer
Dim W = PdfWriter.GetInstance(D, New System.IO.FileStream("C:\test.pdf", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Read))
D.Open()
'Make a new image object
Dim I As New iTextSharp.text.Jpeg(New Uri("file:///" & ImagePath))
'Lower left is (0,0), upper right is (1000,1000)
I.SetAbsolutePosition(DocumentWidth - ImageWidth, 0)
'Add the image
D.Add(I)
D.Close()
place it at the top of the page upside down, and flip the page.
edit:
sorry, i was half kidding. there's an example here of positioning an image using the Image.setAbsolutePosition method. You should be able to calculate the parameters to supply to this function based on the size of the image and the size of the document you're working with.