I built an app that makes some modifications to a picture, changes it's EXIF thumbnail to match the newly created picture and saves it.
It works perfectly under Win 7, but under XP, the EXIF thumbnail remains the same. Here is the part of the code that changes the thumbnail.
Dim MS As New MemoryStream()
Dim bmp_thumb = bmp.GetThumbnailImage(160, 120, Nothing, New IntPtr())
bmp_thumb.Save(MS, ImageFormat.Jpeg)
bmp_thumb.Dispose()
MS.Position = 0
Dim smallthumbbytes As Byte() = MS.ToArray()
Dim PropertyItems = bmp.PropertyItems
PropertyItems(0).Id = &H501B
PropertyItems(0).Type = 1
PropertyItems(0).Len = smallthumbbytes.Length
PropertyItems(0).Value = smallthumbbytes
bmp.SetPropertyItem(PropertyItems(0))
PropertyItems = bmp.PropertyItems
PropertyItems(0).Id = &H5023
PropertyItems(0).Type = CShort(3)
PropertyItems(0).Len = 2
PropertyItems(0).Value = New Byte() {6, 0}
bmp.SetPropertyItem(PropertyItems(0))
bmp.Save(filename)
Should I note, the thumbnail offset of the picture doesn't change under XP too.
Any help appreciated!
Related
This question already has answers here:
C# get thumbnail from file via windows api
(5 answers)
Closed 1 year ago.
I am struggling to find a way on how to get any file thumbnail into my userforms picturebox (The image visible in windows explorer) using visual basic.
I have only found how to do that for image files
Dim image As Image = New Bitmap(file) 'File is a full path to the file
'Resize and preserve aspect ratio
Dim Ratio As Double = CDbl(image.Width / image.Height)
Dim H As Integer = 150
Dim W As Integer = CInt(H / Ratio)
'Set image
.Image = image.GetThumbnailImage(H, W, callback, New IntPtr())
But it doesn't work for any other type of files.
Could someone, please,help me with this code?
Try the following which is adapted from C# get thumbnail from file via windows api
Download/install NuGet package Microsoft-WindowsAPICodePack-Shell
Imports Microsoft.WindowsAPICodePack.Shell
Imports System.IO
...
Private Function GetThumbnailBytes(filename As String, desiredHeight As Integer) As Byte()
Dim thumbnailBytes As Byte()
Using sfile As ShellFile = ShellFile.FromFilePath(filename)
Dim thumbBmp As Bitmap = sfile.Thumbnail.ExtraLargeBitmap
'compute new width
Dim Ratio As Double = CDbl(thumbBmp.Width / thumbBmp.Height)
Dim height As Integer = desiredHeight
Dim width As Integer = CInt(height / Ratio)
'resize
Using resizedBmp As Bitmap = New Bitmap(thumbBmp, width, height)
Using ms As MemoryStream = New MemoryStream()
resizedBmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
thumbnailBytes = ms.ToArray()
End Using
End Using
End Using
Return thumbnailBytes
End Function
Private Sub btnRun_Click(sender As Object, e As EventArgs) Handles btnRun.Click
Using ofd As OpenFileDialog = New OpenFileDialog()
If ofd.ShowDialog() = DialogResult.OK Then
Dim thumbnailBytes = GetThumbnailBytes(ofd.FileName, 60)
Dim thumbnail = GetThumbnail(ofd.FileName, 60)
Using ms As MemoryStream = New MemoryStream(thumbnailBytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
End If
End Using
End Sub
Resources
C# get thumbnail from file via windows api
I create pdfs using iTextSharp and add a footnote and watermark to these using a PdfStamper. This has been working fine. Recently the footers and watermarks have not been appearing when the pdfs are viewed in MS Edge. However, if I view the same pdf in Chrome the footers and watermarks appear correctly.
I store the pdfs in blob storage in Azure.
I have recently changed iTextSharp version from V4.1.2.0 to V5.5.13.
The code for adding watermarks and footers is as follows:
Dim byteArray As Byte()
Using stream As MemoryStream = New MemoryStream
reportBlockBlob.DownloadToStream(stream)
reader = New PdfReader(CType(stream.ToArray(), Byte()))
If reader IsNot Nothing Then
Using stamper As PdfStamper = New PdfStamper(reader, stream)
Dim PageCount As Integer = reader.NumberOfPages
If bReportInvalid Then
For i As Integer = 1 To PageCount
StampWaterMark(stamper, i, "INVALID", fontReport60, 35, New text.BaseColor(70, 70, 255), reader.GetPageSizeWithRotation(i))
Next
ElseIf Not UserRoles.Contains(WaspWAVB.con.csUserRoleCertificateSignOff) Then
For i As Integer = 1 To PageCount
StampWaterMark(stamper, i, "DRAFT", fontReport60, 35, New text.BaseColor(70, 70, 255), reader.GetPageSizeWithRotation(i))
Next
End If
If bAddFooter Then
Dim sRepUCN As String = "UCN"
Dim sCopyright As String = "Copyright"
Dim yPos As Integer = 12
Dim xLeftPos As Integer = 36
Dim xMidPos As Single = 297.5
Dim xRightPos As Integer = 559
For i As Integer = 3 To PageCount - iAppendixCount
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_LEFT, New text.Phrase(sRepUCN, fontMedium), xLeftPos, yPos, 0)
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_CENTER, New text.Phrase(sCopyright, fontMedium), xMidPos, yPos, 0)
Dim rttnPg As Integer = reader.GetPageRotation(i)
If rttnPg <> 0 Then
xRightPos = 806
End If
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_RIGHT, New text.Phrase(String.Format(WaspWAVB.con.csPageXofY, i - 2, PageCount - 2 - iAppendixCount), fontMedium), xRightPos, yPos, 0)
Next
End If
End Using
byteArray = stream.ToArray()
End If
End Using
reportBlockBlob.Properties.ContentType = "application/pdf"
reportBlockBlob.UploadFromByteArray(byteArray, 0, byteArray.Length)
Public Shared Sub StampWaterMark(ByRef stamper As PdfStamper,
ByVal i As Integer,
ByVal watermark As String,
ByVal font As text.Font,
ByVal angle As Single,
ByVal color As text.BaseColor,
ByVal realPageSize As text.Rectangle,
Optional ByVal rect As text.Rectangle = Nothing)
Dim gstate = New PdfGState()
gstate.FillOpacity = 0.1F
gstate.StrokeOpacity = 0.3F
stamper.GetOverContent(i).SaveState()
stamper.GetOverContent(i).SetGState(gstate)
stamper.GetOverContent(i).SetColorFill(color)
stamper.GetOverContent(i).BeginText()
Dim ps = If(rect, realPageSize)
Dim x = (ps.Right + ps.Left) / 2
Dim y = (ps.Bottom + ps.Top) / 2
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_CENTER, New text.Phrase(watermark, font), x, y, angle)
End Sub
I have tried re-arranging the order in which the footer and watermark are applied and commenting out either the addition of watermark or footer. None of this helps.
I use the code to add a footer elsewhere in the code and this works. Where it works, the footer is applied to an individual page. Where it doesn't work I have just collected together pages stored in separate blobs and amalgamated them into one memorystream. The footer and watermark are applied to this.
What is mystifying is that the pdf works fine in Chrome but not in Edge. This works either way round - i.e. if I create it in Chrome and view it in Edge, the footers disappear and if I create it in Edge and view it in Chrome, the footers appear.
Has anyone else seen this problem and knows how to solve it?
My application uses a panel to resemble a template that the user fills in and then prints.
However, they can end up having over 300 pages and my routine that makes the PDF slows down, takes up too much memory and then ultimately crashes with the message of either "OutofMemoryException" or "Invalid Parameter".
The method I use is; loading the revelant information onto the page and then turning it into a bitmap image to place on the PDFPage.
As discovered this really hasn't worked, any suggestions?
Btw I use PDFSharp to make this.
Routine that handles this;
For i = 0 To Count - 1
If i = 0 Then ConditionReportConfig.SwitchPage5(Pages(i), False) Else ConditionReportConfig.SwitchPage5(Pages(i), True)
If WithPics = True And ConditionReportConfig.PG5.PbxAddress(2) <> "" And ConditionReportConfig.PG5.txt_Occupier5.Enabled = True Then
frm_MsgAttachment.pbx_Picture.Image = Image.FromFile(ConditionReportConfig.PG5.PbxAddress(2))
Dim PicPage As PdfPage = PDFDoc.AddPage
PicPage.Orientation = PageOrientation.Landscape
Dim xgr As XGraphics = XGraphics.FromPdfPage(PicPage)
Dim img As XImage
Dim xBitmap As Bitmap
PicPage.Orientation = PageOrientation.Landscape
xBitmap = New Bitmap(2480, 3508)
frm_MsgAttachment.pbx_Picture.DrawToBitmap(xBitmap, New Rectangle(0, 0, xBitmap.Width, xBitmap.Height))
img = xBitmap
xgr.DrawImage(img, 6, 5, 2300, 3508)
xgr.Dispose()
xgr = Nothing
xBitmap.Dispose()
xBitmap = Nothing
GC.Collect()
End If
Dim CDR5 As PdfPage = PDFDoc.AddPage
CDR5.Orientation = PageOrientation.Landscape
GFX = XGraphics.FromPdfPage(CDR5)
Bitmap = New Bitmap(ConditionReportConfig.PG5.Panel1.Width, ConditionReportConfig.PG5.Panel1.Height)
ConditionReportConfig.PG5.Panel1.DrawToBitmap(Bitmap, New Rectangle(0, 0, Bitmap.Width, Bitmap.Height))
BXImage = Bitmap
GFX.ScaleTransform(0.82)
GFX.DrawImage(BXImage, 0, 25)
GFX.Dispose()
GFX = Nothing
Dim valu = frm_Main.pgb_Load.Value
frm_Main.SetPrgBarValue(valu + tem)
Next
I have a picture box array set up
Dim i = 7
Dim s As PictureBox() = New PictureBox(0) {}
s(0) = New PictureBox()
s(0).Image = Image.FromFile("C:\Pic Folder\pic.png")
s(0).Location = New Point(10, 10)
s(0).Size = New Size(50, 50)
however, no image shows up at all. before, when i had declared a new picturebox and put the specifications as the new picturebox (say, foo.Image as opposed to s(0)) it worked fine
I am using Report Viewer for WinForms. The problem i am having is this: I have a form that contains a form which is used to view a local report which work fine, but when I try to render the same report as a PDF, it is cut-off, but in report viewer the same report renders a report on one page. When I render to PDF it cuts it off and the part of the report that was cut-off renders on a 2nd page. So in other words, part of the same report is on page 1, and 2nd half is on 2nd page in the PDF?
Code:
Private Function GetPDfReport() As String
Dim parameters = Me.GetReportParms()
Dim query = Me.GetReportQuery()
Dim rView As Microsoft.Reporting.WinForms.ReportViewer = New Microsoft.Reporting.WinForms.ReportViewer
rView.Dock = DockStyle.Fill
rView.SetDisplayMode(DisplayMode.PrintLayout)
Dim pnl As New Panel()
pnl.Name = "pnlMain"
pnl.Location = New System.Drawing.Point(0, 25)
pnl.Size = New System.Drawing.Size(734, 478)
pnl.Controls.Add(rView)
Dim dbReader As New dbReader()
Dim ds As DataSet = dbReader.DataSet(query)
Dim rds As Microsoft.Reporting.WinForms.ReportDataSource = New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", ds.Tables(0))
rView.ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Local
rView.LocalReport.DataSources.Add(rds)
rView.LocalReport.ReportEmbeddedResource = "EasyDose.rptIncident.rdlc"
If Not IsNothing(parameters) Then
Dim Bound0 As Integer = parameters.GetUpperBound(0)
Dim Bound1 As Integer = parameters.GetUpperBound(1)
For index = 0 To Bound0
Dim rParameter As New ReportParameter(parameters(index, 0), parameters(index, 1))
rView.LocalReport.SetParameters(rParameter)
Next
End If
Dim ps As PageSettings = rView.GetPageSettings
ps.Margins.Top = 0 ' 10mm approx
ps.Margins.Right = 0
ps.Margins.Bottom = 0
ps.Margins.Left = 0
ps.Landscape = False
'ps.PaperSize = New PaperSize("LetterExtra", (9.275 * 100), (12 * 100)) ' Letter paper (8.5 in. by 11 in.) ' Letter extra paper (9.275 in. by 12 in.)
ps.PaperSize = New PaperSize("A4", (8.27 * 100), (11.69 * 100))
rView.RefreshReport()
Dim exePath As String = System.IO.Path.GetDirectoryName(Application.ExecutablePath)
Dim dir As New DirectoryInfo(System.IO.Path.Combine(exePath, "tmpDir"))
Dim file As New FileInfo(System.IO.Path.Combine( _
dir.FullName, String.Format("Patient_Details_{0:yyyyMMdd_hhmmss}.pdf", DateTime.Now)))
If Not dir.Exists Then
dir.Create()
End If
Dim bytes As Byte() = rView.LocalReport.Render("PDF")
Using fs As New System.IO.FileStream(file.FullName, System.IO.FileMode.Create)
fs.Write(bytes, 0, bytes.Length)
fs.Close()
End Using
Return file.FullName
End Function
are you seeing the local report in the embedded ReportViewer using the "Print Layout" option activated? That should show exactly the same output as your printed result.
If you have problems in the PDF is probably caused by the design of the report itself. Check the font, the page size and orientation, the margins, the page breaks.
uisng System.IO;
byte[] rep = reportViewer1.LocalReport.Render("pdf", deviceInfo: "");
// if a certificate warning appears just ignore and re-run
File.WriteAllBytes(filepath+filename+".pdf",rep);