Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Resizing image does not give same file size
Message
De
23/01/2015 00:50:33
 
 
À
22/01/2015 16:59:59
Information générale
Forum:
ASP.NET
Catégorie:
Autre
Versions des environnements
Environment:
VB 9.0
OS:
Windows 8.1
Network:
Windows 2008 Server
Database:
MS SQL Server
Application:
Web
Divers
Thread ID:
01614138
Message ID:
01614151
Vues:
22
After hours of verification, there is in fact something wrong based on the environment.

This is on a Windows Server 2008.

I execute the resizing from a desktop application, the file is resized ok.
I execute the resizing from a Web Service application, the file is resized ok.
I execute the resizing from a Windows Service application, the file is not resized ok.

See the attached image. The file size on disk is always the same. I have done over 40 tests tonight by changing options in the Image class for the resizing and it always work, the file size on disk is always the same. However, the real file size determined by Windows is always a few bytes offset from the other. The offset varies based on the option of resizing quality, size, etc. But, never have I been able to obtain the same real file size.

This is why my CRC32 does not work as we receive files from the Windows Service application which gives a certain number of bytes. And, we receive files from the Web Service application resulting in a different file size.

The code I am using has been used for years. I never had to go in there. I also checked from various sites tonight with various samples and all this is ok. However, I never had to do a resizing from a Windows Service before. This is also the first time I have to do it on a Windows Server 2008.

I know that from Windows 8.1, it does not give the same file size. But, from the same server??? The only different I could see if the .NET project type which might have an effect on the .NET Image object for the resizing that it would not work quite ok on a Windows Service.

I provide here the full class for the Image class. If someone wants to give it a shot to try to adjust it a little bit to fit your own needs, and then run it on a Web Service as well as on a Windows Service, feel free. I really do not know what to try but to give away that class in favor of a commercial utility. All the samples I have seen on the net works. Mine also works. The problem is that I found out this is not working well under a Windows Service. I never found a sample on the net where someone mention a comparism between the final resized file when doing the same process from a Windows Service and a Web Service.

I also have not found any mention that the file resize would be different from Windows 8.1 and Windows Server 2008.

So far, I never found that because we never used or had to verify a CRC32 between various environments. So, the main goal was always to resize a file and it was working. The file image is good. The resize is good. But, when looking deeper into it, only today I found that the file size differs from one environment to another.

Maybe there is a logic for all this and only a commercial utility would be safer to use.
Public Class Image

    Public nCropHeight As Integer = 0
    Public nCropWidth As Integer = 0
    Public cDirectory As String = ""
    Public cFile As String = ""
    Public cFileDestination As String = ""
    Public cMessage As String = ""
    Public lImageHasBeenPreserved As Boolean = False
    Public lResizeButNoCrop As Boolean = False
    Public lVerifyForWidthAndHeight As Boolean = False
    Public nHeight As Integer = 0
    Public nStartXPoint As Integer = 0
    Public nStartYPoint As Integer = 0
    Public nWidth As Integer = 0
    Public oPoint As System.Drawing.Point = New System.Drawing.Point
    Private cCannotSaveHightQuality As String = ""
    Private cDirectoryDoesNotExist As String = ""
    Private cFileDoesNotExist As String = ""
    Private cPixelFormatNotSupported As String = ""
    Private cThisFileIsNotSupported As String = ""
    Private nLanguage As Integer = 0
    Private oApp As App = Nothing
    Private oImage As System.Drawing.Bitmap = Nothing
    Private oProcess As LXProcess = Nothing

    ' This is when we access the class in a desktop mode
    Public Sub New(ByVal toApplication As App)
        oApp = toApplication
        nLanguage = oApp.nLanguage
        Init()
    End Sub

    ' This is when we access the class in a Web or Web Service mode
    Public Sub New(ByVal toProcess As LXProcess)
        oProcess = toProcess
        oApp = oProcess.oApp
        nLanguage = oProcess.nLanguage
        Init()
    End Sub

    Private Function Init() As Boolean

        ' Based on the language
        Select Case nLanguage

            ' English
            Case 1
                cCannotSaveHightQuality = "Cannot save in high quality."
                cDirectoryDoesNotExist = "The directory does not exist."
                cFileDoesNotExist = "The file does not exist."
                cPixelFormatNotSupported = "Pixel format of the image is not supported."
                cThisFileIsNotSupported = "The file ""##File##"" is not supported to be used in this application. It might be corrupted. You " + _
                 "may send this file to support if you think it is valid."

                ' French
            Case 2
                cCannotSaveHightQuality = "Ne peut faire sauver en haute résolution."
                cDirectoryDoesNotExist = "Le répertoire n'existe pas."
                cFileDoesNotExist = "Le fichier n'existe pas."
                cPixelFormatNotSupported = "Le format pixel de cette image n'est pas supporté."
                cThisFileIsNotSupported = "Le fichier ""##File##"" n'est pas supporté pour être utilisé dans cette application. " + _
                 "Il se peut qu'il soit corrompu. Vous pouvez l'envoyer au support si vous pensez qu'il est valide."

                ' Spanish
            Case 3
                cCannotSaveHightQuality = "Cannot save in high quality."
                cDirectoryDoesNotExist = "The directory does not exist."
                cFileDoesNotExist = "The file does not exist"
                cPixelFormatNotSupported = "Pixel format of the image is not supported."
                cThisFileIsNotSupported = "The file ""##File##"" is not supported to be used in this application. It might be corrupted. You " + _
                 "may send this file to support if you think it is valid."

                ' Portuguese
            Case 4
                cCannotSaveHightQuality = "Cannot save in high quality."
                cDirectoryDoesNotExist = "The directory does not exist."
                cFileDoesNotExist = "The file does not exist"
                cPixelFormatNotSupported = "Pixel format of the image is not supported."
                cThisFileIsNotSupported = "The file ""##File##"" is not supported to be used in this application. It might be corrupted. You " + _
                 "may send this file to support if you think it is valid."

        End Select

        Return True
    End Function

    ' Resize an image
    Public Function ImageResize() As Boolean
        Dim lcFile As String = ""
        Dim lnHeightRatio As Integer = 0
        Dim lnRatio As Double = 0
        Dim lnRatioImage As Double = 0
        Dim lnWidthRatio As Integer = 0
        Dim loFinalImage As System.Drawing.Bitmap = Nothing
        Dim loGraphics As System.Drawing.Graphics = Nothing
        Dim loImage As System.Drawing.Bitmap = Nothing
        Dim loImage2 As System.Drawing.Bitmap = Nothing

        ' Reset the values
        lImageHasBeenPreserved = False
        oImage = Nothing

        ' Initialization
        lcFile = Trim(cFile)
        lVerifyForWidthAndHeight = True

        ' Get the proper definition as per the current scope
        If oProcess Is Nothing Then

            ' If the file does not exist
            If Not oApp.FileExist(lcFile) Then
                cMessage = cFileDoesNotExist
                Return False
            End If

        Else

            ' If the file does not exist
            If Not oProcess.FileExist(lcFile) Then
                cMessage = cFileDoesNotExist
                Return False
            End If

        End If

        ' Try to negotiate with the image
        Try
            loImage = New System.Drawing.Bitmap(lcFile)
        Catch loError As Exception
            cMessage = oApp.StrTran(cThisFileIsNotSupported, "##File##", lcFile)
            Return False
        End Try

        ' If we can resize with no crop
        If lResizeButNoCrop Then

            ' Calculate the proper ratio as per the width
            lnHeightRatio = nWidth * loImage.Height / loImage.Width

            ' If the height is greater than the targeted resize height
            If lnHeightRatio > nHeight Then

                ' Adjust the width in regards to that
                nWidth = nHeight * loImage.Width / loImage.Height

                ' Use this flag to bypass the validation when the width and height is defined
                lVerifyForWidthAndHeight = False

            Else

                ' Calculate the proper ratio as per the height
                lnWidthRatio = nHeight * loImage.Width / loImage.Height

                ' If the height is greater than the targeted resize height
                If lnWidthRatio > nWidth Then

                    ' Adjust the height in regards to that
                    nHeight = nWidth * loImage.Height / loImage.Width

                    ' Use this flag to bypass the validation when the width and height is defined
                    lVerifyForWidthAndHeight = False

                End If

            End If

        End If

        ' If the image is already with the proper dimensions
        If nWidth = loImage.Width And nHeight = loImage.Height Then
            lImageHasBeenPreserved = True

            ' This is necessary as the image would remain locked
            loImage.Dispose()

            Return True
        End If

        ' If the width calculated is bigger than the original width or if the height calculated if bigger than the original width
        ' This is in the case the original image is 250x250 and that we would want to resize it to 600x900
        ' In such situation, we preserve the original image otherwise it would be deformed
        If nWidth > loImage.Width Or nHeight > loImage.Height Then
            nWidth = loImage.Width
            nHeight = loImage.Height
        End If

        ' Initialize a new image object on the required dimensions
        loImage2 = New System.Drawing.Bitmap(nWidth, nHeight, loImage.PixelFormat)

        ' If we cannot resize
        If loImage2.PixelFormat = Drawing.Imaging.PixelFormat.Format1bppIndexed Or _
            loImage2.PixelFormat = Drawing.Imaging.PixelFormat.Format4bppIndexed Or _
            loImage2.PixelFormat = Drawing.Imaging.PixelFormat.Format8bppIndexed Or _
            loImage2.PixelFormat = Drawing.Imaging.PixelFormat.Undefined Or _
            loImage2.PixelFormat = Drawing.Imaging.PixelFormat.DontCare Or _
            loImage2.PixelFormat = Drawing.Imaging.PixelFormat.Format16bppArgb1555 Or _
            loImage2.PixelFormat = Drawing.Imaging.PixelFormat.Format16bppGrayScale Then
            cMessage = cPixelFormatNotSupported

            ' This is necessary as the image would remain locked
            loImage.Dispose()

            Return False
        End If

        ' Initialization
        lnRatio = nWidth / nHeight
        lnRatioImage = loImage.Width / loImage.Height

        ' If the ratio of the image is smaller than the calculcated ratio
        If lnRatioImage < lnRatio Then
            nCropWidth = loImage.Width
            nCropHeight = loImage.Width / lnRatio
        Else
            nCropWidth = loImage.Height * lnRatio
            nCropHeight = loImage.Height
        End If

        ' Crop needs it
        oImage = loImage

        ' If we cannot crop
        If Not Crop() Then

            ' This is necessary as the image would remain locked
            loImage.Dispose()

            Return False
        End If

        ' Create the placeholder
        loFinalImage = New System.Drawing.Bitmap(nWidth, nHeight)

        ' Assign the placeholder into the graphic converter
        loGraphics = System.Drawing.Graphics.FromImage(loFinalImage)

        ' Set the parameters
        loGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
        loGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
        loGraphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality
        loGraphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality

        ' Resize the image
        loGraphics.DrawImage(loImage, 0, 0, nWidth, nHeight)

        ' Release the image
        loGraphics.Dispose()

        ' The oImage property can now be assigned to the resized version
        oImage = loFinalImage

        ' If the image has not been altered by the Image class
        If lImageHasBeenPreserved Then
        Else

            ' If we cannot save the image
            If Not SaveAsHighQualityJpegFile() Then

            End If

        End If

        ' Remove this object from memory
        loImage.Dispose()

        ' Reset the values
        cFile = ""
        cFileDestination = ""
        lResizeButNoCrop = False

        Return True
    End Function

    ' Crop an image
    Public Function Crop() As Boolean
        Dim loGraphics As System.Drawing.Graphics = Nothing
        Dim loImage As System.Drawing.Bitmap = Nothing

        ' This is a placeholder
        loImage = New System.Drawing.Bitmap(nCropWidth, nCropHeight)
        loGraphics = System.Drawing.Graphics.FromImage(loImage)

        ' This will use oImage and obtain the new result into loImage
        loGraphics.DrawImage(oImage, New System.Drawing.Rectangle(0, 0, nCropWidth, nCropHeight), _
         nStartXPoint, nStartYPoint, nCropWidth, nCropHeight, System.Drawing.GraphicsUnit.Pixel)

        ' Release this object
        loGraphics.Dispose()

        ' Take the new result and dump it back to oImage
        oImage = loImage

        Return True
    End Function

    ' Save an image into a JPG format
    Public Function SaveAsHighQualityJpegFile() As Boolean
        Dim loEncoderParameters As System.Drawing.Imaging.EncoderParameters = Nothing
        Dim loImageCodecInfo As System.Drawing.Imaging.ImageCodecInfo = Nothing

        ' Set Image codec of JPEG type, the index of JPEG codec is "1"       
        loImageCodecInfo = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()(1)

        ' Set the parameters for defining the quality of the thumbnail... here it is set to 100%
        loEncoderParameters = New System.Drawing.Imaging.EncoderParameters(1)

        loEncoderParameters.Param(0) = New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 95)

        oImage.Save(cFileDestination, loImageCodecInfo, loEncoderParameters)

        Return True
    End Function

    Public Function GetTopLeftStartCropPointForKeepCenter() As Boolean
        oPoint.X = CInt((nWidth - nCropWidth) / 2)

        If nCropWidth + (oPoint.X * 2) < nWidth Then
            oPoint.X -= 1
        End If

        oPoint.Y = CInt((nHeight - nCropHeight) / 2)

        If nCropHeight + (oPoint.Y * 2) < nHeight Then
            oPoint.Y -= 1
        End If

        Return True
    End Function

    ' Remove a border
    Public Function RemoveBorder() As Boolean
        Dim loImage As System.Drawing.Bitmap = Nothing

        ' Get the proper definition as per the current scope
        If oProcess Is Nothing Then

            ' If the file does not exist
            If Not oApp.FileExist(cFile) Then
                cMessage = cFileDoesNotExist
                Return False
            End If

        Else

            ' If the file does not exist
            If Not oProcess.FileExist(cFile) Then
                cMessage = cFileDoesNotExist
                Return False
            End If

        End If

        loImage = New System.Drawing.Bitmap(cFile)

        oImage = loImage
        nStartXPoint = 1
        nStartYPoint = 1
        nWidth = loImage.Width - 2
        nHeight = loImage.Height - 2

        nCropWidth = nWidth
        nCropHeight = nHeight

        ' If we cannot crop the image
        If Not Crop() Then
            cMessage = "Impossible to remove the border"

            ' This is necessary as the image would remain locked
            loImage.Dispose()

            Return False
        End If

        ' This is necessary as the image would remain locked
        loImage.Dispose()

        If Not SaveAsHighQualityJpegFile() Then
            cMessage = cCannotSaveHightQuality
            Return False
        End If

        Return True
    End Function

    ' Remove a border for an entire directory
    Public Function RemoveBorderDirectory() As Boolean
        Dim lnCounter As Integer = 0
        Dim loFileDirectory As FileDirectory = Nothing
        Dim loImage As System.Drawing.Bitmap = Nothing
        Dim loRow As DataRow = Nothing

        ' Get the proper definition as per the current scope
        If oProcess Is Nothing Then
            loFileDirectory = New FileDirectory(oApp)
        Else
            loFileDirectory = New FileDirectory(oProcess)
        End If

        ' If the directory does not exist
        If Not oApp.DirectoryExist(cDirectory) Then
            cMessage = cDirectoryDoesNotExist
            Return False
        End If

        loFileDirectory.cDirectory = cDirectory
        loFileDirectory.AddFilter("*.jpg")

        ' If we cannot get the file
        If Not loFileDirectory.GetFile() Then
            cMessage = loFileDirectory.cMessage
            Return False
        End If

        ' If there is no file
        If loFileDirectory.nCount = 0 Then
            Return True
        End If

        loFileDirectory.Sort("Name")

        ' For each record
        For lnCounter = 0 To loFileDirectory.nCount - 1
            loRow = loFileDirectory.oRows(lnCounter)

            loImage = New System.Drawing.Bitmap(cDirectory + "\" + Trim(loRow("Name")))

            oImage = loImage
            nStartXPoint = 1
            nStartYPoint = 1
            nWidth = loImage.Width - 2
            nHeight = loImage.Height - 2

            nCropWidth = nWidth
            nCropHeight = nHeight

            ' Crop first
            If Not Crop() Then
                cMessage = "Impossible to remove the border"

                ' This is necessary as the image would remain locked
                loImage.Dispose()

                Return False
            End If

            ' This is necessary as the image would remain locked
            loImage.Dispose()

            cFileDestination = cDirectory + "\" + Trim(loRow("Name"))

            If Not SaveAsHighQualityJpegFile() Then
                cMessage = cCannotSaveHightQuality
                Return False
            End If

        Next

        Return True
    End Function

    ' Load an image
    Public Function Load() As Boolean
        Dim lcFile As String = ""
        Dim llSuccess As Boolean = False

        ' Reset the values
        cMessage = ""
        nHeight = 0
        nWidth = 0

        ' Initialization
        lcFile = Trim(cFile)

        ' Get the proper definition as per the current scope
        If oProcess Is Nothing Then

            ' If the file does not exist
            If Not oApp.FileExist(lcFile) Then
                cMessage = cFileDoesNotExist
                Return False
            End If

        Else

            ' If the file does not exist
            If Not oProcess.FileExist(lcFile) Then
                cMessage = cFileDoesNotExist
                Return False
            End If

        End If

        ' Try to load the image
        Try

            ' Load the image
            Using loImage As System.Drawing.Bitmap = New System.Drawing.Bitmap(lcFile)

                ' Initialization
                nWidth = loImage.Width
                nHeight = loImage.Height

            End Using

            llSuccess = True

        Catch loException As Exception
            cMessage = oApp.StrTran(cThisFileIsNotSupported, "##File##", lcFile)
        End Try

        ' Reset the values
        cFile = ""

        Return llSuccess
    End Function

End Class
Michel Fournier
Level Extreme Inc.
Designer, architect, owner of the Level Extreme Platform
Subscribe to the site at https://www.levelextreme.com/Home/DataEntry?Activator=55&NoStore=303
Subscription benefits https://www.levelextreme.com/Home/ViewPage?Activator=7&ID=52
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform