.jpg Datei verkleinern

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von ThuCommix.

    .jpg Datei verkleinern

    Hi,

    ich komme gerade aus dem Urlaub. :D

    Mit meiner Digicam mache ich .jpg Bilder die ich dann von meinem Laptop per e-Mail verschicke. Allerdings sind diese Bilder sehr groß. Und weil ich im Urlaub meist nur über wifi oder USB-Dongle ans Netz komme, dauert die Übertragung von einem einzigen Bild oft viel zu lang. Deshalb verkleinere ich die Bilder mit "Paint", dann klappt das Versenden besser.

    Könnte ich so etwas per VB realisieren, also ein bestimmtes Bild auf einen frei wählbaren Prozentsatz verkleinern.

    LG
    Peter
    Ja, ob Prozentual oder neue feste Breite oder Höhe.

    VB.NET-Quellcode

    1. Private Function ScaleImageToWidth(img As Bitmap, new_width As Integer) As Bitmap
    2. Dim factor As Double = img.Width / img.Height
    3. Dim nbmp As New Bitmap(new_width, CInt(new_width / factor))
    4. Using g As Graphics = Graphics.FromImage(nbmp)
    5. g.DrawImage(img, 0, 0, nbmp.Width, nbmp.Height)
    6. End Using
    7. Return nbmp
    8. End Function
    9. Private Function ScaleImageToHeight(img As Bitmap, new_height As Integer) As Bitmap
    10. Dim factor As Double = img.Height / img.Width
    11. Dim nbmp As New Bitmap(CInt(new_height / factor), new_height)
    12. Using g As Graphics = Graphics.FromImage(nbmp)
    13. g.DrawImage(img, 0, 0, nbmp.Width, nbmp.Height)
    14. End Using
    15. Return nbmp
    16. End Function
    17. Private Function SizeImagePercent(img As Bitmap, percent As Double) As Bitmap
    18. Dim factor As Double = img.Height / img.Width
    19. Dim new_width As Integer = CInt(img.Width / 100 * percent)
    20. Dim new_height As Integer = CInt(new_width * factor)
    21. Dim nbmp As New Bitmap(new_width, new_height)
    22. Using g As Graphics = Graphics.FromImage(nbmp)
    23. g.DrawImage(img, 0, 0, nbmp.Width, nbmp.Height)
    24. End Using
    25. Return nbmp
    26. End Function
    Recht herzlichen Dank für die Funktionen!

    LG
    Peter

    [edit] Die Antwort kam schneller als ich mein Edit ... danke auch für die nachfolgende Antwort!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Peter329“ ()

    VB.NET-Quellcode

    1. dim DeinBild as new Bitmap("C:\DEINBILD.jpg")


    Aufrufe :

    VB.NET-Quellcode

    1. Picturebox.Image = SizeImagePercent(DeinBild,50)



    zum abspeichern könntest du es so machen :

    VB.NET-Quellcode

    1. SizeImagePercent(DeinBild,50).save("C:\TOLLESBILD.jpg")
    MFG 0x426c61636b4e6574776f726b426974
    InOffical VB-Paradise IRC-Server
    webchat.freenode.net/
    Channel : ##vbparadise

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „BlackNetworkBit“ ()

    So, die Sache mit dem Einlesen und Speichern klappt soweit.

    VB.NET-Quellcode

    1. Dim img As Bitmap = CType(Image.FromFile(strInPicture), Bitmap)
    2. SizeImagePercent(img, numPercentage.Value).Save(strOutPicture)


    Leider wird die Datei nur für 10 und 20 Prozent kleiner. Danach wird die Datei größer als das Original:

    Original Größe: 1.232 KB

    Verkleinerte Größe:

    10 % : 190 KB
    20 % : 708 KB
    30 %: 1.497 KB

    Ich hab versucht, das Coding nachzuvollziehen. Könnte es sein, dass beim Berechnen etwas schief läuft. Da werden long Zahlen dividiert - ist das ganzzahlig, d.h. werden da Nachkomma Stellen abgeschnitten ... ?

    LG
    Peter
    Lese dir dies mal durch:

    msdn.microsoft.com/de-de/library/bb882583%28v=vs.110%29.aspx

    damit könntest du vieleicht ein paar Bytes sparen.

    Edit: Die Doubles hab ich nur verwendet um eine möglichst massstabsgetreue Scallierung zu machen, würde mann dort eine Integer verwenden wäre dies nicht möglich. Klar werden die gerundet/abgeschnitten beim erzeugen der neuen Bitmap, da eine Bitmap als Argumente nur Ganzzahlen zulässt.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Derfuhr“ ()

    Peter329 schrieb:


    Leider wird die Datei nur für 10 und 20 Prozent kleiner. Danach wird die Datei größer als das Original..

    Hallo Peter,

    ich habe ein bisschen für Dich gespielt :) ..
    Hier hast Du eine Version, die genau das tut was Du willst (musst alles nur auf Deine Bedürfnisse anpassen):

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Drawing.Drawing2D
    2. Imports System.Drawing.Imaging
    3. Public Class Form1
    4. ''' <summary>
    5. ''' Push the button ;)
    6. ''' </summary>
    7. ''' <param name="sender"></param>
    8. ''' <param name="e"></param>
    9. ''' <remarks></remarks>
    10. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    11. ' Dein Ursprungsbild
    12. Dim DeinBild As New Bitmap("D:\test.jpg")
    13. ' verkleinerte, interpolierte und komprimierte Versionen
    14. JPEGCompression(PicResizeByPercent(DeinBild, 10), "D:\10.jpg", 75)
    15. JPEGCompression(PicResizeByPercent(DeinBild, 20), "D:\20.jpg", 75)
    16. JPEGCompression(PicResizeByPercent(DeinBild, 30), "D:\30.jpg", 75)
    17. JPEGCompression(PicResizeByPercent(DeinBild, 40), "D:\40.jpg", 75)
    18. JPEGCompression(PicResizeByPercent(DeinBild, 50), "D:\50.jpg", 75)
    19. JPEGCompression(PicResizeByPercent(DeinBild, 60), "D:\60.jpg", 75)
    20. JPEGCompression(PicResizeByPercent(DeinBild, 70), "D:\70.jpg", 75)
    21. JPEGCompression(PicResizeByPercent(DeinBild, 80), "D:\80.jpg", 75)
    22. JPEGCompression(PicResizeByPercent(DeinBild, 90), "D:\90.jpg", 75)
    23. End Sub
    24. ''' <summary>
    25. ''' Diese Funktion ändert die Größe eines Bilds und gibt es als Bitmap zurück. Hier ist die Prozentuale größe veränderbar.
    26. ''' </summary>
    27. ''' <remarks>
    28. ''' Autor: Tim Hartwick http://dotnet-snippets.de/snippet/bildgroesse-prozentual-veraendern-interpoliert/338
    29. ''' </remarks>
    30. ''' <param name="SourceImage">Das Bild dessen größe verändert werden soll</param>
    31. ''' <param name="Percent">Die neue größe des Bilds in Prozent (100% = Normale größe)</param>
    32. Public Function PicResizeByPercent(ByVal SourceImage As Image, ByVal Percent As Short) As Bitmap
    33. Dim NewWidth As Integer = ((Percent / 100) * SourceImage.Width)
    34. Dim NewHeigth As Integer = ((Percent / 100) * SourceImage.Height)
    35. Dim NewImage As New Bitmap(NewWidth, NewHeigth)
    36. Using G As Graphics = Graphics.FromImage(NewImage)
    37. G.InterpolationMode = InterpolationMode.HighQualityBicubic
    38. G.DrawImage(SourceImage, New Rectangle(0, 0, NewWidth, NewHeigth))
    39. End Using
    40. Return NewImage
    41. End Function
    42. ''' <summary>
    43. ''' Diese Funktion Komprimiert ein JPEG Bild und speichert dieses als neues Bild ab
    44. ''' </summary>
    45. ''' <remarks>
    46. ''' Autor: Tim Hartwick http://dotnet-snippets.de/snippet/jpeg-bild-komprimieren/167
    47. ''' </remarks>
    48. ''' <param name="Image">Das Bild welches komprimiert werden soll</param>
    49. ''' <param name="OutPutFile">Der Pfad des neuen komprimierten Bilds</param>
    50. ''' <param name="Qualitiy">Die Qualitätseinstellung 0-100</param>
    51. Public Sub JPEGCompression(ByVal Image As Image, ByVal OutPutFile As String, ByVal Qualitiy As Integer)
    52. Dim ImageCodecs() As ImageCodecInfo
    53. Dim ImageParameters As EncoderParameters
    54. ImageCodecs = ImageCodecInfo.GetImageEncoders()
    55. ImageParameters = New EncoderParameters(1)
    56. ImageParameters.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Qualitiy)
    57. Image.Save(OutPutFile, ImageCodecs(1), ImageParameters)
    58. End Sub
    59. End Class


    Verkleinert wird bikubisch interpoliert und gespeichert wird komprimiert (änderbar).
    Quellenangaben der Methoden sind im Header.

    LG,
    Bruno
    Hallo Peter,

    und weils einfach besser aussieht, hier noch die Version, wo die Bilder noch ein bisschen geschärft werden (einstellbar).
    Und nun auch Strict ON 8-) ..

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Drawing.Drawing2D
    3. Imports System.Drawing.Imaging
    4. Imports System.Runtime.InteropServices
    5. Public Class Form1
    6. ''' <summary>
    7. ''' Push the button ;)
    8. ''' </summary>
    9. ''' <param name="sender"></param>
    10. ''' <param name="e"></param>
    11. ''' <remarks></remarks>
    12. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    13. ' Dein Ursprungsbild
    14. Dim DeinBild As New Bitmap("D:\test.jpg")
    15. ' verkleinerte, interpolierte, geschärfte und komprimierte Versionen
    16. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 10), 0.3), "D:\10.jpg", 75)
    17. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 20), 0.3), "D:\20.jpg", 75)
    18. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 30), 0.3), "D:\30.jpg", 75)
    19. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 40), 0.3), "D:\40.jpg", 75)
    20. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 50), 0.3), "D:\50.jpg", 75)
    21. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 60), 0.3), "D:\60.jpg", 75)
    22. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 70), 0.3), "D:\70.jpg", 75)
    23. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 80), 0.3), "D:\80.jpg", 75)
    24. JPEGCompression(Sharpen(PicResizeByPercent(DeinBild, 90), 0.3), "D:\90.jpg", 75)
    25. End Sub
    26. ''' <summary>
    27. ''' Diese Funktion ändert die Größe eines Bilds und gibt es als Bitmap zurück. Hier ist die Prozentuale größe veränderbar.
    28. ''' </summary>
    29. ''' <remarks>
    30. ''' Autor: Tim Hartwick http://dotnet-snippets.de/snippet/bildgroesse-prozentual-veraendern-interpoliert/338
    31. ''' </remarks>
    32. ''' <param name="SourceImage">Das Bild dessen größe verändert werden soll</param>
    33. ''' <param name="Percent">Die neue größe des Bilds in Prozent (100% = Normale größe)</param>
    34. Private Function PicResizeByPercent(ByVal SourceImage As Image, ByVal Percent As Short) As Bitmap
    35. Dim NewWidth As Integer = CInt(((Percent / 100) * SourceImage.Width))
    36. Dim NewHeigth As Integer = CInt(((Percent / 100) * SourceImage.Height))
    37. Dim NewImage As New Bitmap(NewWidth, NewHeigth)
    38. Using G As Graphics = Graphics.FromImage(NewImage)
    39. G.InterpolationMode = InterpolationMode.HighQualityBicubic
    40. G.DrawImage(SourceImage, New Rectangle(0, 0, NewWidth, NewHeigth))
    41. End Using
    42. Return NewImage
    43. End Function
    44. ''' <summary>
    45. ''' Diese Funktion Komprimiert ein JPEG Bild und speichert dieses als neues Bild ab
    46. ''' </summary>
    47. ''' <remarks>
    48. ''' Autor: Tim Hartwick http://dotnet-snippets.de/snippet/jpeg-bild-komprimieren/167
    49. ''' </remarks>
    50. ''' <param name="Image">Das Bild welches komprimiert werden soll</param>
    51. ''' <param name="OutPutFile">Der Pfad des neuen komprimierten Bilds</param>
    52. ''' <param name="Qualitiy">Die Qualitätseinstellung 0-100</param>
    53. Private Sub JPEGCompression(ByVal Image As Image, ByVal OutPutFile As String, ByVal Qualitiy As Integer)
    54. Dim ImageCodecs() As ImageCodecInfo
    55. Dim ImageParameters As EncoderParameters
    56. ImageCodecs = ImageCodecInfo.GetImageEncoders()
    57. ImageParameters = New EncoderParameters(1)
    58. ImageParameters.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Qualitiy)
    59. Image.Save(OutPutFile, ImageCodecs(1), ImageParameters)
    60. End Sub
    61. ''' <summary>
    62. ''' Bild schärfen
    63. ''' </summary>
    64. ''' <param name="SourceImage"></param>
    65. ''' <param name="SharpenFac"></param>
    66. ''' <returns></returns>
    67. ''' <remarks></remarks>
    68. Private Function Sharpen(ByVal SourceImage As Bitmap, ByVal SharpenFac As Double) As Bitmap
    69. Using OrgBmp As New Bitmap(SourceImage)
    70. Dim Stride As Integer = OrgBmp.Width * 4
    71. Dim BmpData As Byte() = New Byte((OrgBmp.Height * Stride) - 1) {}
    72. Dim OrgBmbData As BitmapData = Nothing
    73. OrgBmbData = OrgBmp.LockBits(New Rectangle(0, 0, OrgBmp.Width, OrgBmp.Height), ImageLockMode.ReadOnly, OrgBmp.PixelFormat)
    74. Marshal.Copy(OrgBmbData.Scan0, BmpData, 0, BmpData.Length)
    75. OrgBmp.UnlockBits(OrgBmbData)
    76. Dim Bmp32Pos As New Integer
    77. Dim Red As New Double
    78. Dim Green As New Double
    79. Dim Blue As New Double
    80. For Y As Integer = 0 To OrgBmp.Height - 1
    81. For X As Integer = 0 To OrgBmp.Width - 1
    82. Bmp32Pos = (Y * Stride) + (X * 4)
    83. Red = BmpData(Bmp32Pos + 2)
    84. Green = BmpData(Bmp32Pos + 1)
    85. Blue = BmpData(Bmp32Pos + 0)
    86. If Y - 1 >= 0 Then
    87. If X - 1 >= 0 Then
    88. Bmp32Pos = ((Y - 1) * Stride) + ((X - 1) * 4)
    89. Red = Math.Abs(Red + (SharpenFac * (Red - BmpData(Bmp32Pos + 2))))
    90. Green = Math.Abs(Green + (SharpenFac * (Green - BmpData(Bmp32Pos + 1))))
    91. Blue = Math.Abs(Blue + (SharpenFac * (Blue - BmpData(Bmp32Pos + 0))))
    92. If Red > 255 Then Red = 255
    93. If Green > 255 Then Green = 255
    94. If Blue > 255 Then Blue = 255
    95. End If
    96. End If
    97. Bmp32Pos = (Y * Stride) + (X * 4)
    98. BmpData(Bmp32Pos + 2) = CByte(Red)
    99. BmpData(Bmp32Pos + 1) = CByte(Green)
    100. BmpData(Bmp32Pos + 0) = CByte(Blue)
    101. Next
    102. Next
    103. OrgBmbData = OrgBmp.LockBits(New Rectangle(0, 0, OrgBmp.Width, OrgBmp.Height), ImageLockMode.WriteOnly, OrgBmp.PixelFormat)
    104. Marshal.Copy(BmpData, 0, OrgBmbData.Scan0, BmpData.Length)
    105. OrgBmp.UnlockBits(OrgBmbData)
    106. OrgBmbData = Nothing
    107. Return New Bitmap(OrgBmp)
    108. End Using
    109. End Function
    110. End Class


    LG,
    Bruno
    Ich würde das Coding gern ausprobieren.

    Leider gibt es (neben einigen "strict on" Meldungen) einen Fehler, den ich nicht beheben kann:

    VB.NET-Quellcode

    1. G.InterpolationMode = InterpolationMode.HighQualityBicubic


    Fehler 1 "InterpolationMode" wurde nicht deklariert. Auf das Objekt kann aufgrund seiner Schutzstufe möglicherweise nicht zugegriffen werden.

    Da fehlt wohl irgend ein Import ...

    LG
    Peter

    [edit] Da hast du mich "überholt" ... ich schau in die neue Version gleich mal rein! :D
    Das mit den Imports hat sich geklärt. Ist alles richtig!

    Deine Routine klappt hervorragen! Die Compression ist jetzt super!

    Recht herzlichen Dank für deine Hilfe. Im nächsten Urlaub hab ich jetzt sehr viel weniger Arbeit! :D

    LG
    Peter
    Neee, Effekte brauch ich nicht. :D

    Also, ich hab die Routinen jetzt auf Herz und Nieren getestet.

    Die "PicResize" Routine passt die Bildgröße an, aber dabei wird die Dateigröße ggfs. massiv aufgebläht.

    Die "Sharpen" Routine wirkt sehr gut und entfernt die "Ecken", die beim Verkleinern entstehen.

    Die "JPGCompression" Routine ist einfach super! Die verkleinert das Datenvolumen drastisch! Auch ohne "Resize" wird die Datei entschieden kleiner, selbst wenn man die Bildgröße überhaupt nicht verändert! Vermutlich wird da jede Menge an Ballast aus der JPG Darstellung entfernt. Ein Beispiel: Bei einer Verkleinerung auf 30% schrumpft eine Datei von 1.2 MB auf gerade mal 94 KB ohne nennenswerte Einbußen an der Qualität. Da kann man nicht meckern. :D

    Ich bin begeistert! Das sind genau die Routinen, die ich gesucht habe.

    Also, recht herzlichen Dank noch einmal an "dylab" und natürlich auch an alle anderen Ratgeber!

    Have a great New Year 2014 everybody!
    LG
    Peter