Results 1 to 8 of 8

Thread: Modification de compression d'un JPEG affiché en PictureBox

  1. #1

    Thread Starter
    New Member
    Join Date
    Apr 2020
    Posts
    10

    Modification de compression d'un JPEG affiché en PictureBox

    Bonjour,

    J'ai un petit problème "pratique" que je n'arrive pas à résoudre (malgré mes recherches sur le net).

    Pour simplifier:

    J'affiche une image dans une PictureBox et cherche à modifier son taux de compression afin de diminuer la taille du fichier.

    N'ayant pas trouvé d'autre moyen, je teste divers taux afin de voir le résultat qui me convient le mieux (équilibre qualité image/taille de fichier).

    Actuellement, je prends le chemin "long" (à mon avis) :

    Code:
                
                Dim imgStreamRead As Stream = New FileStream("Test.jpg", FileMode.Open, FileAccess.Read, FileShare.Read)
                Dim jpgEncoder As New JpegBitmapEncoder
                jpgEncoder.Frames.Add(BitmapFrame.Create(imgStreamRead))
    
                Dim imgStreamWrite As Stream = New FileStream("Test_W.jpg", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
                jpgEncoder.QualityLevel = 50    ' ---- exemple ----
                jpgEncoder.Save(imgStreamWrite)
    
                TextBox1.Text = (imgStreamWrite.Length \ 1024).ToString   ' ---- affichage de la taille du fichier résultat ---------     
                imgStreamWrite.Close()
                imgStreamRead.Close()
                My.Computer.FileSystem.DeleteFile("Test_W.jpg")
    Question :

    Plutôt que de lire le fichier image par le "FileSream" pour pouvoir charger la "BitmapFrame" dans le "JpgEncoder", ne peut-on directement partir de l'image qui est affichée dans la PictureBox ?

    Cela éviterait une relecture du fichier image "Test.jpg" et serait sans doute plus rapide.

    Quelqu'un sait-il comment faire ?

    J'ai essayé pas mal de "machins" mais je n'arrive pas à récupérer les infos de "BitmapFrame" nécessaires au "JpgEncoder".

    Merci à Tou(te)s d'avance
    Dom

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Modification de compression d'un JPEG affiché en PictureBox

    Parlez vous Anglais?
    This is an English speaking forum. It’ll impede your progress if you can’t ask in English...

  3. #3

    Thread Starter
    New Member
    Join Date
    Apr 2020
    Posts
    10

    Re: Modification de compression d'un JPEG affiché en PictureBox

    Oh, sorry, I translate in English (viva Reverso !)

    Changing the compression of a JPEG displayed in PictureBox



    Hello,

    I have a small "practical" problem that I can’t solve (despite my research on the net).

    To simplify:

    I display an image in a PictureBox and try to change its compression ratio to decrease the file size.

    Having not found another way, I test various rates to see the result that suits me best (balance image quality/file size).

    Currently, I am taking the "long" path (in my opinion):

    Code:
                Dim imgStreamRead As Stream = New FileStream("Test.jpg", FileMode.Open, FileAccess.Read, FileShare.Read)
                Dim jpgEncoder As New JpegBitmapEncoder
                jpgEncoder.Frames.Add(BitmapFrame.Create(imgStreamRead))
    
                Dim imgStreamWrite As Stream = New FileStream("Test_W.jpg", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
                jpgEncoder.QualityLevel = 50    ' ---- exemple ----
                jpgEncoder.Save(imgStreamWrite)
    
                TextBox1.Text = (imgStreamWrite.Length \ 1024).ToString   ' ---- affichage de la taille du fichier résultat ---------     
                imgStreamWrite.Close()
                imgStreamRead.Close()
                My.Computer.FileSystem.DeleteFile("Test_W.jpg")
    Question:

    Rather than reading the image file by the "FileSream" to be able to load the "BitmapFrame" in the "JpgEncoder", can we not directly start from the image that is displayed in the PictureBox?

    This would avoid a new read of the image file "Test.jpg" and would probably be faster.

    Does anyone know how to do that?

    I’ve tried a lot of "stuff" but I can’t get the "BitmapFrame" info needed for the "JpgEncoder".

    Thanks to Everybody in advance
    Dom

  4. #4
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Modification de compression d'un JPEG affiché en PictureBox

    You could just get the image, then save it as .png. Best all round solution. Smaller file size and good quality...

  5. #5

    Thread Starter
    New Member
    Join Date
    Apr 2020
    Posts
    10

    Re: Modification de compression d'un JPEG affiché en PictureBox

    Quote Originally Posted by .paul. View Post
    You could just get the image, then save it as .png. Best all round solution. Smaller file size and good quality...
    Thanks !

    Yes, I knew that... but it's not the problem.
    They must stay in jpg format for compatibility with older soft.

    Another idea ?

  6. #6
    Fanatic Member
    Join Date
    Aug 2004
    Location
    Essex, UK
    Posts
    750

    Re: Modification de compression d'un JPEG affiché en PictureBox

    This is some old code I use to save jpegs at different quality settings:

    Code:
    Imports System.Drawing.Imaging
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    
            Dim bm As Bitmap = CType(PicureBox1.Image, Bitmap)
    
            ' Jpeg quality settings
            Dim jpgEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
    
            ' Create an Encoder object based on the GUID for the Quality parameter category 
            Dim myEncoder As System.Drawing.Imaging.Encoder = System.Drawing.Imaging.Encoder.Quality
    
            ' Create an EncoderParameters object 
            ' An EncoderParameters object has an array of EncoderParameter objects 
            ' In this case, there is only one EncoderParameter object in the array 
            Dim myEncoderParameters As New EncoderParameters(1)
    
            Dim myEncoderParameter As New EncoderParameter(myEncoder, 10L) ' Set quality - data type = long
            myEncoderParameters.Param(0) = myEncoderParameter
    
            bm.Save("F:\Pictures\animal2.jpg", jpgEncoder, myEncoderParameters)
    
        End Sub
    
        Private Function GetEncoder(ByVal format As ImageFormat) As ImageCodecInfo
    
            Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
    
            Dim codec As ImageCodecInfo
            For Each codec In codecs
                If codec.FormatID = format.Guid Then
                    Return codec
                End If
            Next codec
            Return Nothing
    
        End Function

  7. #7

    Thread Starter
    New Member
    Join Date
    Apr 2020
    Posts
    10

    Re: Modification de compression d'un JPEG affiché en PictureBox

    Hi,
    Sorry for delay...

    I tested your code (Function GetEncoder stay in other part of code)
    - Note that the image is in a PictureBox in a Panel, the path of the file in in the Tag of this PB

    Code:
                Dim sFImgR As String = ListeFichier.sDiSv + Panel1.Controls.Item(iNCt).Tag.Replace(".jpg", "_T.jpg")
                Dim bm As Bitmap = CType(CType(Panel1.Controls.Item(iNCt), PictureBox).Image, Bitmap)
    
                ' Jpeg quality settings
                Dim jpgEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
    
                ' Create an Encoder object based on the GUID for the Quality parameter category 
                Dim myEncoder As System.Drawing.Imaging.Encoder = System.Drawing.Imaging.Encoder.Quality
    
                ' Create an EncoderParameters object 
                ' An EncoderParameters object has an array of EncoderParameter objects 
                ' In this case, there is only one EncoderParameter object in the array 
                Dim myEncoderParameters As New EncoderParameters(1)
    
                Dim myEncoderParameter As New EncoderParameter(myEncoder, 10L) ' Set quality - data type = long
                myEncoderParameters.Param(0) = myEncoderParameter
    
                bm.Save(sFImgR, jpgEncoder, myEncoderParameters)

    Many Thanks... but I get back this error in the "bm.save" :

    A first chance exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
    An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
    Additional information: Une erreur générique s'est produite dans GDI+.
    And the file is created with null length.

    Did you know why ?
    Thanks in advance for your help
    Dom
    Last edited by Domino59b; Oct 28th, 2020 at 12:53 PM.

  8. #8
    Fanatic Member
    Join Date
    Aug 2004
    Location
    Essex, UK
    Posts
    750

    Re: Modification de compression d'un JPEG affiché en PictureBox

    I guess the original file is locked. Are you trying to overwrite the original file?

    This should fix it:

    Code:
    Using ms As IO.MemoryStream = New IO.MemoryStream
    
          bm.Save(ms, jpgEncoder, myEncoderParameters)
    
    End Using

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width