FlexCel image explorer (VB.Net / netframework)
Note
This demo is available in your FlexCel installation at <FlexCel Install Folder>\samples\vb\VS2022\netframework\10.API\30.FlexCelImageExplorer and also at https://github.com/tmssoftware/TMS-FlexCel.NET-demos/tree/master/vb/VS2022/netframework/Modules/10.API/30.FlexCelImageExplorer
Overview
This is an application that will show all the images in an Excel file, to show their real size and bit depth. It will also allow you to extract those images to files. Note that the first time you open a file it can take some time, as it opens ALL the xls files on the folder and extracts all the image information so it can highlight files with problems.
Concepts
How to use the API to read the images on a file.
How to convert the images to 256 colors or black and white using GDI+
On the left pane, files in red are files that have a cropped image. (that is, the image stored is larger than the image shown on Excel). Having this cropped image only consumes disk space, and makes rendering to pdf slower, as the image has to be decoded, cropped to the real size and encoded again.
Bold entries on the left pane are images with true color and transparency. Those images can get very big quite fast, so it is better if you can convert them to indexed color. Also, file with true color and transparency have to be re-encoded when exporting to pdf, making the process slower.
Files
AssemblyInfo.vb
Imports System.Reflection
Imports System.Runtime.CompilerServices
'
' General Information about an assembly is controlled through the following
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
'
<Assembly: AssemblyTitle("")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyConfiguration("")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("")>
<Assembly: AssemblyCopyright("(c) 2002 - 2014 TMS Software")>
<Assembly: AssemblyTrademark("")>
<Assembly: AssemblyCulture("")>
'
' Version information for an assembly consists of the following four values:
'
' Major Version
' Minor Version
' Build Number
' Revision
'
' You can specify all the values or you can default the Revision and Build Numbers
' by using the '*' as shown below:
<Assembly: AssemblyVersion("6.2.1.0")>
'
' In order to sign your assembly you must specify a key to use. Refer to the
' Microsoft .NET Framework documentation for more information on assembly signing.
'
' Use the attributes below to control which key is used for signing.
'
' Notes:
' (*) If no key is specified, the assembly is not signed.
' (*) KeyName refers to a key that has been installed in the Crypto Service
' Provider (CSP) on your machine. KeyFile refers to a file which contains
' a key.
' (*) If the KeyFile and the KeyName values are both specified, the
' following processing occurs:
' (1) If the KeyName can be found in the CSP, that key is used.
' (2) If the KeyName does not exist and the KeyFile does exist, the key
' in the KeyFile is installed into the CSP and used.
' (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
' When specifying the KeyFile, the location of the KeyFile should be
' relative to the project output directory which is
' %Project Directory%\obj\<configuration>. For example, if your KeyFile is
' located in the project directory, you would specify the AssemblyKeyFile
' attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
' (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
' documentation for more information on this.
'
<Assembly: AssemblyDelaySign(False)>
<Assembly: AssemblyKeyFile("")>
<Assembly: AssemblyKeyName("")>
MainForm.Designer.vb
Imports System.Collections
Imports System.ComponentModel
Imports System.IO
Imports FlexCel.Core
Imports FlexCel.XlsAdapter
Namespace FlexCelImageExplorer
Partial Public Class mainForm
Inherits System.Windows.Forms.Form
Private openFileDialog1 As System.Windows.Forms.OpenFileDialog
Private panel1 As System.Windows.Forms.Panel
Private splitter1 As System.Windows.Forms.Splitter
Private panel3 As System.Windows.Forms.Panel
Private WithEvents FilesListBox As System.Windows.Forms.ListBox
Private lblFolder As System.Windows.Forms.Label
Private dataGrid As System.Windows.Forms.DataGrid
Private dataSet1 As System.Data.DataSet
Private ImageDataTable As System.Data.DataTable
Private Index As System.Data.DataColumn
Private Cell1 As System.Data.DataColumn
Private Cell2 As System.Data.DataColumn
Private [cType] As System.Data.DataColumn
Private cText As System.Data.DataColumn
Private Description As System.Data.DataColumn
Private dataColumn1 As System.Data.DataColumn
Private panel4 As System.Windows.Forms.Panel
Private splitter2 As System.Windows.Forms.Splitter
Private dataColumn2 As System.Data.DataColumn
Private PreviewBox As System.Windows.Forms.PictureBox
Private dataColumn3 As System.Data.DataColumn
Private saveImageDialog As System.Windows.Forms.SaveFileDialog
Private dataColumn4 As System.Data.DataColumn
Private components As System.ComponentModel.IContainer = Nothing
''' <summary>
''' Clean up any resources being used.
''' </summary>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If components IsNot Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region "Windows Form Designer generated code"
''' <summary>
''' Required method for Designer support - do not modify
''' the contents of this method with the code editor.
''' </summary>
Private Sub InitializeComponent()
Dim resources As New System.ComponentModel.ComponentResourceManager(GetType(mainForm))
Me.openFileDialog1 = New System.Windows.Forms.OpenFileDialog()
Me.panel1 = New System.Windows.Forms.Panel()
Me.FilesListBox = New System.Windows.Forms.ListBox()
Me.panel3 = New System.Windows.Forms.Panel()
Me.lblFolder = New System.Windows.Forms.Label()
Me.splitter1 = New System.Windows.Forms.Splitter()
Me.dataGrid = New System.Windows.Forms.DataGrid()
Me.ImageDataTable = New System.Data.DataTable()
Me.dataColumn4 = New System.Data.DataColumn()
Me.Index = New System.Data.DataColumn()
Me.Cell1 = New System.Data.DataColumn()
Me.Cell2 = New System.Data.DataColumn()
Me.cType = New System.Data.DataColumn()
Me.cText = New System.Data.DataColumn()
Me.Description = New System.Data.DataColumn()
Me.dataColumn1 = New System.Data.DataColumn()
Me.dataColumn2 = New System.Data.DataColumn()
Me.dataColumn3 = New System.Data.DataColumn()
Me.dataSet1 = New System.Data.DataSet()
Me.panel4 = New System.Windows.Forms.Panel()
Me.PreviewBox = New System.Windows.Forms.PictureBox()
Me.splitter2 = New System.Windows.Forms.Splitter()
Me.saveImageDialog = New System.Windows.Forms.SaveFileDialog()
Me.mainToolbar = New System.Windows.Forms.ToolStrip()
Me.cbScanFolder = New System.Windows.Forms.ToolStripButton()
Me.btnOpenFile = New System.Windows.Forms.ToolStripButton()
Me.toolStripSeparator1 = New System.Windows.Forms.ToolStripSeparator()
Me.btnShowInExcel = New System.Windows.Forms.ToolStripButton()
Me.btnSaveAsImage = New System.Windows.Forms.ToolStripButton()
Me.btnExit = New System.Windows.Forms.ToolStripButton()
Me.btnInfo = New System.Windows.Forms.ToolStripButton()
Me.toolStripSeparator2 = New System.Windows.Forms.ToolStripSeparator()
Me.btnStretchPreview = New System.Windows.Forms.ToolStripButton()
Me.panel1.SuspendLayout()
Me.panel3.SuspendLayout()
CType(Me.dataGrid, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.ImageDataTable, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.dataSet1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.panel4.SuspendLayout()
CType(Me.PreviewBox, System.ComponentModel.ISupportInitialize).BeginInit()
Me.mainToolbar.SuspendLayout()
Me.SuspendLayout()
'
' openFileDialog1
'
Me.openFileDialog1.DefaultExt = "xls"
Me.openFileDialog1.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm|Excel 97/2003|*.xls|Excel 2007|*.xlsx;*.xlsm|All " & "files|*.*"
Me.openFileDialog1.Title = "Open an Excel File"
'
' panel1
'
Me.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
Me.panel1.Controls.Add(Me.FilesListBox)
Me.panel1.Controls.Add(Me.panel3)
Me.panel1.Dock = System.Windows.Forms.DockStyle.Left
Me.panel1.Location = New System.Drawing.Point(0, 38)
Me.panel1.Name = "panel1"
Me.panel1.Size = New System.Drawing.Size(176, 400)
Me.panel1.TabIndex = 4
'
' FilesListBox
'
Me.FilesListBox.Dock = System.Windows.Forms.DockStyle.Fill
Me.FilesListBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
Me.FilesListBox.Location = New System.Drawing.Point(0, 40)
Me.FilesListBox.Name = "FilesListBox"
Me.FilesListBox.Size = New System.Drawing.Size(172, 356)
Me.FilesListBox.TabIndex = 1
' Me.FilesListBox.DrawItem += New System.Windows.Forms.DrawItemEventHandler(Me.FilesListBox_DrawItem)
' Me.FilesListBox.SelectedIndexChanged += New System.EventHandler(Me.FilesListBox_SelectedIndexChanged)
'
' panel3
'
Me.panel3.BackColor = System.Drawing.Color.DarkSeaGreen
Me.panel3.Controls.Add(Me.lblFolder)
Me.panel3.Dock = System.Windows.Forms.DockStyle.Top
Me.panel3.Location = New System.Drawing.Point(0, 0)
Me.panel3.Name = "panel3"
Me.panel3.Size = New System.Drawing.Size(172, 40)
Me.panel3.TabIndex = 0
'
' lblFolder
'
Me.lblFolder.Dock = System.Windows.Forms.DockStyle.Fill
Me.lblFolder.ForeColor = System.Drawing.Color.Black
Me.lblFolder.Location = New System.Drawing.Point(0, 0)
Me.lblFolder.Name = "lblFolder"
Me.lblFolder.Size = New System.Drawing.Size(172, 40)
Me.lblFolder.TabIndex = 0
Me.lblFolder.Text = "No Selected Folder."
'
' splitter1
'
Me.splitter1.Location = New System.Drawing.Point(176, 38)
Me.splitter1.Name = "splitter1"
Me.splitter1.Size = New System.Drawing.Size(3, 400)
Me.splitter1.TabIndex = 5
Me.splitter1.TabStop = False
'
' dataGrid
'
Me.dataGrid.CaptionText = "No file selected"
Me.dataGrid.DataMember = ""
Me.dataGrid.DataSource = Me.ImageDataTable
Me.dataGrid.Dock = System.Windows.Forms.DockStyle.Top
Me.dataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText
Me.dataGrid.Location = New System.Drawing.Point(179, 38)
Me.dataGrid.Name = "dataGrid"
Me.dataGrid.PreferredColumnWidth = 120
Me.dataGrid.ReadOnly = True
Me.dataGrid.Size = New System.Drawing.Size(709, 128)
Me.dataGrid.TabIndex = 7
'
' ImageDataTable
'
Me.ImageDataTable.Columns.AddRange(New System.Data.DataColumn() { Me.dataColumn4, Me.Index, Me.Cell1, Me.Cell2, Me.cType, Me.cText, Me.Description, Me.dataColumn1, Me.dataColumn2, Me.dataColumn3})
Me.ImageDataTable.TableName = "ImageDataTable"
'
' dataColumn4
'
Me.dataColumn4.ColumnName = "Sheet"
'
' Index
'
Me.Index.ColumnName = "Index"
'
' Cell1
'
Me.Cell1.Caption = "Width (Pixels)"
Me.Cell1.ColumnName = "Width (Pixels)"
'
' Cell2
'
Me.Cell2.Caption = "Height (Pixels)"
Me.Cell2.ColumnName = "Height (Pixels)"
'
' cType
'
Me.cType.ColumnName = "Type"
'
' cText
'
Me.cText.Caption = "Image Format"
Me.cText.ColumnName = "Image Format"
'
' Description
'
Me.Description.Caption = "Uncompressed size"
Me.Description.ColumnName = "Uncompressed size"
'
' dataColumn1
'
Me.dataColumn1.Caption = "Name"
Me.dataColumn1.ColumnName = "Name"
'
' dataColumn2
'
Me.dataColumn2.ColumnMapping = System.Data.MappingType.Hidden
Me.dataColumn2.ColumnName = "Image"
Me.dataColumn2.DataType = GetType(Byte())
'
' dataColumn3
'
Me.dataColumn3.ColumnName = "Cropped"
Me.dataColumn3.DataType = GetType(Boolean)
'
' dataSet1
'
Me.dataSet1.DataSetName = "ImageDataSet"
Me.dataSet1.Locale = New System.Globalization.CultureInfo("")
Me.dataSet1.Tables.AddRange(New System.Data.DataTable() { Me.ImageDataTable})
'
' panel4
'
Me.panel4.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
Me.panel4.Controls.Add(Me.PreviewBox)
Me.panel4.Dock = System.Windows.Forms.DockStyle.Fill
Me.panel4.Location = New System.Drawing.Point(179, 169)
Me.panel4.Name = "panel4"
Me.panel4.Size = New System.Drawing.Size(709, 269)
Me.panel4.TabIndex = 8
'
' PreviewBox
'
Me.PreviewBox.Dock = System.Windows.Forms.DockStyle.Fill
Me.PreviewBox.Location = New System.Drawing.Point(0, 0)
Me.PreviewBox.Name = "PreviewBox"
Me.PreviewBox.Size = New System.Drawing.Size(705, 265)
Me.PreviewBox.TabIndex = 0
Me.PreviewBox.TabStop = False
'
' splitter2
'
Me.splitter2.Dock = System.Windows.Forms.DockStyle.Top
Me.splitter2.Location = New System.Drawing.Point(179, 166)
Me.splitter2.Name = "splitter2"
Me.splitter2.Size = New System.Drawing.Size(709, 3)
Me.splitter2.TabIndex = 9
Me.splitter2.TabStop = False
'
' mainToolbar
'
Me.mainToolbar.Items.AddRange(New System.Windows.Forms.ToolStripItem() { Me.cbScanFolder, Me.btnOpenFile, Me.toolStripSeparator1, Me.btnShowInExcel, Me.btnSaveAsImage, Me.btnExit, Me.btnInfo, Me.toolStripSeparator2, Me.btnStretchPreview})
Me.mainToolbar.Location = New System.Drawing.Point(0, 0)
Me.mainToolbar.Name = "mainToolbar"
Me.mainToolbar.Size = New System.Drawing.Size(888, 38)
Me.mainToolbar.TabIndex = 12
Me.mainToolbar.Text = "toolStrip1"
'
' cbScanFolder
'
Me.cbScanFolder.CheckOnClick = True
Me.cbScanFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text
Me.cbScanFolder.Image = (CType(resources.GetObject("cbScanFolder.Image"), System.Drawing.Image))
Me.cbScanFolder.ImageTransparentColor = System.Drawing.Color.Magenta
Me.cbScanFolder.Name = "cbScanFolder"
Me.cbScanFolder.Size = New System.Drawing.Size(122, 35)
Me.cbScanFolder.Text = "Scan all files in folder"
Me.cbScanFolder.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'
' btnOpenFile
'
Me.btnOpenFile.Image = (CType(resources.GetObject("btnOpenFile.Image"), System.Drawing.Image))
Me.btnOpenFile.ImageTransparentColor = System.Drawing.Color.Magenta
Me.btnOpenFile.Name = "btnOpenFile"
Me.btnOpenFile.Size = New System.Drawing.Size(59, 35)
Me.btnOpenFile.Text = "Open file"
Me.btnOpenFile.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
' Me.btnOpenFile.Click += New System.EventHandler(Me.btnOpenFile_Click)
'
' toolStripSeparator1
'
Me.toolStripSeparator1.Name = "toolStripSeparator1"
Me.toolStripSeparator1.Size = New System.Drawing.Size(6, 38)
'
' btnShowInExcel
'
Me.btnShowInExcel.Image = (CType(resources.GetObject("btnShowInExcel.Image"), System.Drawing.Image))
Me.btnShowInExcel.ImageTransparentColor = System.Drawing.Color.Magenta
Me.btnShowInExcel.Name = "btnShowInExcel"
Me.btnShowInExcel.Size = New System.Drawing.Size(82, 35)
Me.btnShowInExcel.Text = "Show in Excel"
Me.btnShowInExcel.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
' Me.btnShowInExcel.Click += New System.EventHandler(Me.btnOpen_Click)
'
' btnSaveAsImage
'
Me.btnSaveAsImage.Image = (CType(resources.GetObject("btnSaveAsImage.Image"), System.Drawing.Image))
Me.btnSaveAsImage.ImageTransparentColor = System.Drawing.Color.Magenta
Me.btnSaveAsImage.Name = "btnSaveAsImage"
Me.btnSaveAsImage.Size = New System.Drawing.Size(85, 35)
Me.btnSaveAsImage.Text = "Save as image"
Me.btnSaveAsImage.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
' Me.btnSaveAsImage.Click += New System.EventHandler(Me.btnSaveImage_Click)
'
' btnExit
'
Me.btnExit.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.btnExit.Image = (CType(resources.GetObject("btnExit.Image"), System.Drawing.Image))
Me.btnExit.ImageTransparentColor = System.Drawing.Color.Magenta
Me.btnExit.Name = "btnExit"
Me.btnExit.Size = New System.Drawing.Size(59, 35)
Me.btnExit.Text = " E&xit "
Me.btnExit.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
' Me.btnExit.Click += New System.EventHandler(Me.btnExit_Click)
'
' btnInfo
'
Me.btnInfo.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.btnInfo.Image = (CType(resources.GetObject("btnInfo.Image"), System.Drawing.Image))
Me.btnInfo.ImageTransparentColor = System.Drawing.Color.Magenta
Me.btnInfo.Name = "btnInfo"
Me.btnInfo.Size = New System.Drawing.Size(74, 35)
Me.btnInfo.Text = "Information"
Me.btnInfo.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
' Me.btnInfo.Click += New System.EventHandler(Me.btnInfo_Click)
'
' toolStripSeparator2
'
Me.toolStripSeparator2.Name = "toolStripSeparator2"
Me.toolStripSeparator2.Size = New System.Drawing.Size(6, 38)
'
' btnStretchPreview
'
Me.btnStretchPreview.CheckOnClick = True
Me.btnStretchPreview.Image = (CType(resources.GetObject("btnStretchPreview.Image"), System.Drawing.Image))
Me.btnStretchPreview.ImageTransparentColor = System.Drawing.Color.Magenta
Me.btnStretchPreview.Name = "btnStretchPreview"
Me.btnStretchPreview.Size = New System.Drawing.Size(92, 35)
Me.btnStretchPreview.Text = "Stretch preview"
Me.btnStretchPreview.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
' Me.btnStretchPreview.Click += New System.EventHandler(Me.btnStretchPreview_Click)
'
' mainForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(888, 438)
Me.Controls.Add(Me.panel4)
Me.Controls.Add(Me.splitter2)
Me.Controls.Add(Me.dataGrid)
Me.Controls.Add(Me.splitter1)
Me.Controls.Add(Me.panel1)
Me.Controls.Add(Me.mainToolbar)
Me.Name = "mainForm"
Me.Text = "FlexCel Image Explorer"
Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
Me.panel1.ResumeLayout(False)
Me.panel3.ResumeLayout(False)
CType(Me.dataGrid, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.ImageDataTable, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.dataSet1, System.ComponentModel.ISupportInitialize).EndInit()
Me.panel4.ResumeLayout(False)
CType(Me.PreviewBox, System.ComponentModel.ISupportInitialize).EndInit()
Me.mainToolbar.ResumeLayout(False)
Me.mainToolbar.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
#End Region
Private mainToolbar As ToolStrip
Private WithEvents btnOpenFile As ToolStripButton
Private toolStripSeparator1 As ToolStripSeparator
Private WithEvents btnShowInExcel As ToolStripButton
Private WithEvents btnSaveAsImage As ToolStripButton
Private WithEvents btnExit As ToolStripButton
Private WithEvents btnInfo As ToolStripButton
Private toolStripSeparator2 As ToolStripSeparator
Private WithEvents btnStretchPreview As ToolStripButton
Private cbScanFolder As ToolStripButton
End Class
End Namespace
MainForm.vb
Imports System.Collections
Imports System.ComponentModel
Imports System.IO
Imports FlexCel.Core
Imports FlexCel.XlsAdapter
Namespace FlexCelImageExplorer
''' <summary>
''' Image Explorer.
''' </summary>
Partial Public Class mainForm
Inherits System.Windows.Forms.Form
Public Sub New()
InitializeComponent()
AddHandler GetCurrencyManager.CurrentChanged, AddressOf CurrentRowChanged
ResizeToolbar(mainToolbar)
End Sub
Private Sub ResizeToolbar(ByVal toolbar As ToolStrip)
Using gr As Graphics = CreateGraphics()
Dim xFactor As Double = gr.DpiX / 96.0
Dim yFactor As Double = gr.DpiY / 96.0
toolbar.ImageScalingSize = New Size(CInt(Fix(24 * xFactor)), CInt(Fix(24 * yFactor)))
toolbar.Width = 0 'force a recalc of the buttons.
End Using
End Sub
Private CurrentFilename As String = Nothing
Private CompressForm As TCompressForm
Private ReadOnly Property GetCurrencyManager() As CurrencyManager
Get
Return CType(Me.BindingContext(dataGrid.DataSource, dataGrid.DataMember), CurrencyManager)
End Get
End Property
Private ReadOnly Property GetImagePos() As Integer
Get
Return GetCurrencyManager.Position
End Get
End Property
Private Sub btnExit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExit.Click
Close()
End Sub
Private Sub btnOpenFile_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOpenFile.Click
If openFileDialog1.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
Return
End If
OpenFile(openFileDialog1.FileName)
If cbScanFolder.Checked Then
FillListBox()
End If
End Sub
Private Function GetHasCrop(ByVal ImgProps As TImageProperties) As Boolean
Return ImgProps.CropArea.CropFromLeft <> 0 OrElse ImgProps.CropArea.CropFromRight <> 0 OrElse ImgProps.CropArea.CropFromTop <> 0 OrElse ImgProps.CropArea.CropFromBottom <> 0
End Function
Private Sub FillListBox()
lblFolder.Text = "Files on folder: " & Path.GetDirectoryName(openFileDialog1.FileName)
Dim di As New DirectoryInfo(Path.GetDirectoryName(openFileDialog1.FileName))
Dim Fi() As FileInfo = di.GetFiles("*.xls")
FilesListBox.Items.Clear()
Dim Files(Fi.Length - 1) As TImageInfo
For k As Integer = 0 To Fi.Length - 1
Dim f As FileInfo = Fi(k)
Dim HasCrop As Boolean = False
Dim HasARGB As Boolean = False
Dim x1 As New XlsFile()
Dim HasImages As Boolean = False
Try
x1.Open(f.FullName)
For sheet As Integer = 1 To x1.SheetCount
x1.ActiveSheet = sheet
For i As Integer = x1.ImageCount To 1 Step -1
HasImages = True
Dim ip As TImageProperties = x1.GetImageProperties(i)
If Not HasCrop Then
HasCrop = GetHasCrop(ip)
End If
Dim imgType As TXlsImgType = TXlsImgType.Unknown
Using ms As New MemoryStream()
x1.GetImage(i, imgType, ms)
Dim PngInfo As FlexCel.Pdf.TPngInformation = FlexCel.Pdf.TPdfPng.GetPngInfo(ms)
If PngInfo IsNot Nothing Then
HasARGB = PngInfo.ColorType = 6
End If
End Using
Next i
Next sheet
Catch e1 As Exception
Files(k) = New TImageInfo(f, False, False, False, False)
Continue For
End Try
Files(k) = New TImageInfo(f, True, HasCrop, HasImages, HasARGB)
Next k
FilesListBox.Items.AddRange(Files)
End Sub
Private Sub OpenFile(ByVal FileName As String)
ImageDataTable.Rows.Clear()
Try
Dim Xls As New XlsFile(True)
CurrentFilename = FileName
Xls.Open(FileName)
For sheet As Integer = 1 To Xls.SheetCount
Xls.ActiveSheet = sheet
For i As Integer = Xls.ImageCount To 1 Step -1
Dim ImageType As TXlsImgType = TXlsImgType.Unknown
Dim ImgBytes() As Byte = Xls.GetImage(i, ImageType)
Dim ImgProps As TImageProperties = Xls.GetImageProperties(i)
Dim ImgData(ImageDataTable.Columns.Count - 1) As Object
ImgData(0) = Xls.SheetName
ImgData(1) = i
ImgData(4) = ImageType.ToString()
ImgData(7) = Xls.GetImageName(i)
ImgData(8) = ImgBytes
ImgData(9) = GetHasCrop(ImgProps)
Using ms As New MemoryStream(ImgBytes)
Dim PngInfo As FlexCel.Pdf.TPngInformation = FlexCel.Pdf.TPdfPng.GetPngInfo(ms)
If PngInfo IsNot Nothing Then
ImgData(2) = PngInfo.Width
ImgData(3) = PngInfo.Height
Dim s As String = String.Empty
Dim bpp As Integer = 0
If (PngInfo.ColorType And 4) <> 0 Then
s &= "ALPHA-"
bpp = 1
End If
If (PngInfo.ColorType And 2) = 0 Then
s &= "Grayscale -" & (1 << PngInfo.BitDepth).ToString() & " shades. "
bpp = 1
Else
If (PngInfo.ColorType And 1) = 0 Then
bpp += 3
s &= "RGB - " & (PngInfo.BitDepth * (bpp)).ToString() & "bpp. "
Else
s &= "Indexed - " & (1 << PngInfo.BitDepth).ToString() & " colors. "
bpp = 1
End If
End If
ImgData(5) = s
ImgData(6) = (Math.Round(PngInfo.Width * PngInfo.Height * PngInfo.BitDepth * bpp / 8F / 1024F)).ToString() & " kb."
Else
ms.Position = 0
Try
Using Img As Image = Image.FromStream(ms)
Dim Bmp As Bitmap = TryCast(Img, Bitmap)
If Bmp IsNot Nothing Then
ImgData(5) = Bmp.PixelFormat.ToString() & "bpp"
End If
ImgData(2) = Img.Width
ImgData(3) = Img.Height
End Using
Catch e1 As Exception
ImgData(2) = -1
ImgData(3) = -1
ImgData(5) = Nothing
ImgData(8) = Nothing
End Try
End If
End Using
ImageDataTable.Rows.Add(ImgData)
Next i
Next sheet
Catch ex As Exception
MessageBox.Show(ex.Message, "Error")
dataGrid.CaptionText = "No file selected"
CurrentFilename = Nothing
Return
End Try
dataGrid.CaptionText = "Selected file: " & FileName
CurrentRowChanged(GetCurrencyManager, Nothing)
End Sub
Private Sub FilesListBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles FilesListBox.SelectedIndexChanged
Dim ImageInfo As TImageInfo = CType(FilesListBox.SelectedItem, TImageInfo)
If ImageInfo Is Nothing Then
Return
End If
OpenFile(ImageInfo.File.FullName)
End Sub
Public Sub CurrentRowChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim Pos As Integer = CType(sender, BindingManagerBase).Position
If Pos < 0 Then
PreviewBox.Image = Nothing
Return
End If
Dim r As DataRowCollection = dataSet1.Tables("ImageDataTable").Rows
If Pos < 0 OrElse Pos >= r.Count Then
PreviewBox.Image = Nothing
Else
Dim ImgData() As Byte = TryCast(r(Pos).ItemArray(8), Byte())
If ImgData Is Nothing Then
PreviewBox.Image = Nothing
Else
Using ms As New MemoryStream(ImgData)
PreviewBox.Image = Image.FromStream(ms)
End Using
End If
End If
End Sub
Private Sub btnOpen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnShowInExcel.Click
If CurrentFilename Is Nothing Then
MessageBox.Show("There is no open file")
Return
End If
System.Diagnostics.Process.Start(CurrentFilename)
End Sub
Private Sub btnConvert_Click(ByVal sender As Object, ByVal e As System.EventArgs)
'This is not yet implemented...
Dim Pos As Integer = GetImagePos
If Pos < 0 Then
MessageBox.Show("There is no selected image", "Error")
Return
End If
If CompressForm Is Nothing Then
CompressForm = New TCompressForm()
End If
CompressForm.ImageToUse = CType(dataSet1.Tables("ImageDataTable").Rows(Pos).ItemArray(8), Byte())
CompressForm.XlsFilename = CurrentFilename
CompressForm.ShowDialog()
End Sub
Private Sub FilesListBox_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles FilesListBox.DrawItem
If e.Index < 0 Then
Return
End If
e.DrawBackground()
Dim myBrush As Brush = Brushes.Black
Dim ImageInfo As TImageInfo = CType(CType(sender, ListBox).Items(e.Index), TImageInfo)
If Not ImageInfo.HasImages Then
myBrush = Brushes.Silver
End If
If ImageInfo.HasCrop Then
myBrush = Brushes.Red
End If
Dim NewStyle As FontStyle
If ImageInfo.HasARGB Then
NewStyle = FontStyle.Bold
Else
NewStyle = FontStyle.Regular
End If
Using MyFont As New Font(e.Font, NewStyle)
e.Graphics.DrawString(ImageInfo.ToString(), MyFont, myBrush, e.Bounds, StringFormat.GenericDefault)
End Using
e.DrawFocusRectangle()
End Sub
Private Sub btnSaveImage_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSaveAsImage.Click
Dim Pos As Integer = GetImagePos
If Pos < 0 Then
MessageBox.Show("There is no selected image to save", "Error")
Return
End If
Dim ext As String = dataSet1.Tables("ImageDataTable").Rows(Pos).ItemArray(4).ToString().ToLower()
saveImageDialog.DefaultExt = ext
saveImageDialog.Filter = ext & " Images|*." & ext
If saveImageDialog.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
Return
End If
Dim ImgData() As Byte = CType(dataSet1.Tables("ImageDataTable").Rows(Pos).ItemArray(8), Byte())
Using fs As New FileStream(saveImageDialog.FileName, FileMode.Create)
fs.Write(ImgData, 0, ImgData.Length)
End Using
End Sub
Private Sub btnInfo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInfo.Click
MessageBox.Show("FlexCelImageExplorer is a small application targeted to reduce the size on images inside Excel files." & vbLf & "On the current version you can see the image properties and extract the images to disk.")
End Sub
Private Sub btnStretchPreview_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnStretchPreview.Click
If btnStretchPreview.Checked Then
PreviewBox.SizeMode = PictureBoxSizeMode.StretchImage
Else
PreviewBox.SizeMode = PictureBoxSizeMode.Normal
End If
End Sub
End Class
Friend Class TImageInfo
Friend File As FileInfo
Friend IsValidFile As Boolean
Friend HasCrop As Boolean
Friend HasImages As Boolean
Friend HasARGB As Boolean
Public Sub New(ByVal aFile As FileInfo, ByVal aIsValidFile As Boolean, ByVal aHasCrop As Boolean, ByVal aHasImages As Boolean, ByVal aHasARGB As Boolean)
File = aFile
HasCrop = aHasCrop
HasImages = aHasImages
IsValidFile = aIsValidFile
HasARGB = aHasARGB
End Sub
Public Overrides Function ToString() As String
If Not IsValidFile Then
Return " (*)" & File.ToString()
End If
Return File.ToString()
End Function
End Class
End Namespace
Program.vb
Namespace FlexCelImageExplorer
Friend NotInheritable Class Program
Private Sub New()
End Sub
''' <summary>
''' The main entry point for the application.
''' </summary>
<STAThread> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New mainForm())
End Sub
End Class
End Namespace
TCompressForm.Designer.vb
Imports System.Collections
Imports System.ComponentModel
Imports System.IO
Namespace FlexCelImageExplorer
Partial Public Class TCompressForm
Inherits System.Windows.Forms.Form
Private label1 As System.Windows.Forms.Label
Private edPercent As System.Windows.Forms.NumericUpDown
Private cbPixelFormat As System.Windows.Forms.ComboBox
Private WithEvents btnOk As System.Windows.Forms.Button
Private WithEvents btnCancel As System.Windows.Forms.Button
Private panel1 As System.Windows.Forms.Panel
Private panel2 As System.Windows.Forms.Panel
Private pictureBox1 As System.Windows.Forms.PictureBox
Private cbTransparent As System.Windows.Forms.CheckBox
''' <summary>
''' Required designer variable.
''' </summary>
Private components As System.ComponentModel.Container = Nothing
''' <summary>
''' Clean up any resources being used.
''' </summary>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If components IsNot Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region "Windows Form Designer generated code"
''' <summary>
''' Required method for Designer support - do not modify
''' the contents of this method with the code editor.
''' </summary>
Private Sub InitializeComponent()
Me.label1 = New System.Windows.Forms.Label()
Me.edPercent = New System.Windows.Forms.NumericUpDown()
Me.cbPixelFormat = New System.Windows.Forms.ComboBox()
Me.btnOk = New System.Windows.Forms.Button()
Me.btnCancel = New System.Windows.Forms.Button()
Me.panel1 = New System.Windows.Forms.Panel()
Me.panel2 = New System.Windows.Forms.Panel()
Me.pictureBox1 = New System.Windows.Forms.PictureBox()
Me.cbTransparent = New System.Windows.Forms.CheckBox()
CType(Me.edPercent, System.ComponentModel.ISupportInitialize).BeginInit()
Me.panel1.SuspendLayout()
Me.panel2.SuspendLayout()
Me.SuspendLayout()
'
' label1
'
Me.label1.Location = New System.Drawing.Point(16, 8)
Me.label1.Name = "label1"
Me.label1.Size = New System.Drawing.Size(144, 16)
Me.label1.TabIndex = 0
Me.label1.Text = "Change Resolution (%):"
'
' edPercent
'
Me.edPercent.Increment = New System.Decimal(New Integer() { 5, 0, 0, 0})
Me.edPercent.Location = New System.Drawing.Point(176, 8)
Me.edPercent.Minimum = New System.Decimal(New Integer() { 10, 0, 0, 0})
Me.edPercent.Name = "edPercent"
Me.edPercent.Size = New System.Drawing.Size(48, 20)
Me.edPercent.TabIndex = 2
Me.edPercent.Value = New System.Decimal(New Integer() { 60, 0, 0, 0})
'
' cbPixelFormat
'
Me.cbPixelFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.cbPixelFormat.Items.AddRange(New Object() { "1bpp (Black and White)", "8bpp (256 colors optimized palette)", "24bpp (true color)"})
Me.cbPixelFormat.Location = New System.Drawing.Point(16, 40)
Me.cbPixelFormat.Name = "cbPixelFormat"
Me.cbPixelFormat.Size = New System.Drawing.Size(208, 21)
Me.cbPixelFormat.TabIndex = 3
'
' btnOk
'
Me.btnOk.Anchor = System.Windows.Forms.AnchorStyles.Bottom
Me.btnOk.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnOk.Location = New System.Drawing.Point(148, 168)
Me.btnOk.Name = "btnOk"
Me.btnOk.TabIndex = 4
Me.btnOk.Text = "Ok"
' Me.btnOk.Click += New System.EventHandler(Me.btnOk_Click)
'
' btnCancel
'
Me.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom
Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnCancel.Location = New System.Drawing.Point(244, 168)
Me.btnCancel.Name = "btnCancel"
Me.btnCancel.TabIndex = 5
Me.btnCancel.Text = "Cancel"
' Me.btnCancel.Click += New System.EventHandler(Me.btnCancel_Click)
'
' panel1
'
Me.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
Me.panel1.Controls.Add(Me.cbTransparent)
Me.panel1.Controls.Add(Me.edPercent)
Me.panel1.Controls.Add(Me.cbPixelFormat)
Me.panel1.Controls.Add(Me.label1)
Me.panel1.Location = New System.Drawing.Point(16, 16)
Me.panel1.Name = "panel1"
Me.panel1.Size = New System.Drawing.Size(240, 136)
Me.panel1.TabIndex = 6
'
' panel2
'
Me.panel2.Anchor = (CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) Or System.Windows.Forms.AnchorStyles.Left) Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles))
Me.panel2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
Me.panel2.Controls.Add(Me.pictureBox1)
Me.panel2.Location = New System.Drawing.Point(280, 16)
Me.panel2.Name = "panel2"
Me.panel2.Size = New System.Drawing.Size(168, 136)
Me.panel2.TabIndex = 7
'
' pictureBox1
'
Me.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill
Me.pictureBox1.Location = New System.Drawing.Point(0, 0)
Me.pictureBox1.Name = "pictureBox1"
Me.pictureBox1.Size = New System.Drawing.Size(164, 132)
Me.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
Me.pictureBox1.TabIndex = 0
Me.pictureBox1.TabStop = False
'
' cbTransparent
'
Me.cbTransparent.Location = New System.Drawing.Point(16, 88)
Me.cbTransparent.Name = "cbTransparent"
Me.cbTransparent.TabIndex = 4
Me.cbTransparent.Text = "Transparent"
'
' TCompressForm
'
Me.AcceptButton = Me.btnOk
Me.CancelButton = Me.btnCancel
Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(472, 214)
Me.Controls.Add(Me.panel2)
Me.Controls.Add(Me.panel1)
Me.Controls.Add(Me.btnCancel)
Me.Controls.Add(Me.btnOk)
Me.Name = "TCompressForm"
Me.Text = "Compression Options..."
' Me.Load += New System.EventHandler(Me.TCompressForm_Load)
CType(Me.edPercent, System.ComponentModel.ISupportInitialize).EndInit()
Me.panel1.ResumeLayout(False)
Me.panel2.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
#End Region
End Class
End Namespace
TCompressForm.vb
Imports System.Collections
Imports System.ComponentModel
Imports System.IO
Namespace FlexCelImageExplorer
''' <summary>
''' Summary description for TCompressForm.
''' </summary>
Partial Public Class TCompressForm
Inherits System.Windows.Forms.Form
Public Sub New()
'
' Required for Windows Form Designer support
'
InitializeComponent()
cbPixelFormat.SelectedIndex = 2
'
' TODO: Add any constructor code after InitializeComponent call
'
End Sub
Private FImageToUse() As Byte
Private FXlsFilename As String
Friend Property ImageToUse() As Byte()
Get
Return FImageToUse
End Get
Set(ByVal value As Byte())
FImageToUse = value
Using ms As New MemoryStream(value)
pictureBox1.Image = Image.FromStream(ms)
End Using
End Set
End Property
Friend Property XlsFilename() As String
Get
Return FXlsFilename
End Get
Set(ByVal value As String)
FXlsFilename = value
End Set
End Property
Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Close()
End Sub
Private Sub TCompressForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub btnOk_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOk.Click
Close()
End Sub
End Class
End Namespace