vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevAniGif - als kostenlose Vollversion auf unserer vb@rchiv CD Vol.5  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 24.10.11 16:43

Ich möchte eine Bitmap (original Bitmap.FromFile("xyz.bmp")) laden, ihr eine von mir bestimmte Resolution verpassen Bitmap.SetResolution(300,300) und dann als JPG wieder speichern.

Das Laden und SetResolution klappt. Die Auflösung der Bitmap beträgt nach SetResolution tatsächlich 300 DPI, wenn ich sie aber speichere "Bitmap.Save(Pfad,Imaging.ImageFormat.Jpeg)" wird die Auflösung nach erneutem Einlesen wieder mit 96 DPI (Standard) angegeben.

Mit dem ImageEncoder kann ich die Auflösung leider nicht festlegen, Qualität etc. sind mir in diesem Fall nicht so wichtig.

Hier der Code, den es zu verbessern gilt:
Dim vorschau as Bitmap
vorschau = Bitmap.FromFile("abc")
vorschau.SetResolution(300,300)
vorschau.Save("abcde",Imaging.ImageFormat.Jpeg)
vorschau.dispose()
Ich habe das bisher per Freeimage.DLL ganz locker lösen können, aber obwohl ich als Plattform für's Debuggen x86 eingestellt habe, will das Programm die FreeImage.DLL nicht erkennen. Außerdem meine ich, das muß doch auch mit VB Net zu schaffen sein.
Ich wäre für Hilfe sehr dankbar
Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Manfred X
Datum: 24.10.11 18:10

Hallo!
Dim vorschau As Bitmap
vorschau = CType(Bitmap.FromFile("abc.jpg"), Bitmap)
 
Dim output As New Bitmap(vorschau.Width, vorschau.Height, vorschau.PixelFormat)
 
output.SetResolution(300, 300)
 
Using g As Graphics = Graphics.FromImage(output)
      g.DrawImage(vorschau, 0, 0)
End Using
output.Save("abcde.jpg", Imaging.ImageFormat.Jpeg)
vorschau.Dispose()
output.Dispose()
Aufpassen. Die Größe des Output-Bildes muss anhand der
DPI-Werte entsprechend umgerechnet werden.

MfG
Manfred
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 24.10.11 18:30

Suuper, ich hab's jetzt so schnell nicht testen können, vermute aber, dass es klappt.
Auf jeden Fall erstmal vielen Dank! Melde mich dann wieder.

Ich denke, mein Fehler war, dass ich die Bitmap nicht auf einen 300 mal 300 DPI-Unterlage neu gezeichnet habe.

Was die Größe angeht, will ich mit dem Setzen der Auflösung erreichen, dass anständige Bildbearbeitungsprogramme, wie Photoshop etc. solch ein JPG standardmäßig in der von mir gewünschten Größe ausdrucken. Dieser Trick klappt vorzüglich.

Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 24.10.11 19:52

So, getestet - klappt prima!
Die "Umrechnung" der Größe sieht bei mir folgendermaßen aus:

Dim vorschau, vorschau1 as Bitmap
vorschau = CType(Bitmap.FromFile(tempfile), Bitmap)
vorschau1 = New Bitmap(vorschau.Width, vorschau.Height)
vorschau1.SetResolution(300, 300)
Using g As Graphics = Graphics.FromImage(vorschau1)
   g.DrawImage(vorschau, 0, 0, vorschau.Width, vorschau.Height)
End Using
vorschau1.Save("Abcd.jpg",Imaging.ImageFormat.Jpeg)
vorschau.Dispose()
vorschau1.Dispose()
Wenn ich DrawImage nicht auf das ursprüngliche Rechteck (vorschau.width, vorschau.height)beschränkte, würde die Zeichnung (in meinem Falle) 300/96(momentane Bildschirmauflösung) mal so gross auf die Unterlage gezeichnet werden. Also hätte ich nur ca. 32% der Abbildung auf der Unterlage vorschau1.
So erhalte ich nun ein vollstädiges Bild in Originalgrösse, dass aber als Auflösung statt 96DPI 300DPI im Bitmapheader stehen hat.
Gebe ich dieses Bild jetzt z.B. an Photoshop weiter und lasse es dort ausdrucken, wird es standardmäßig genau so gross ausgedruckt, wie es erstellt wurde. Also eine mit 300 DPI eingescannte Din A4 - Seite würde bei hoher Qualität auch wieder als Din A4-Seite ausgedruckt werden, und zwar genau!!

Das war der Zweck des ganzen Aufstandes (zu verwirrend?)
Nochmal besten Dank!
Kalle

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Manfred X
Datum: 25.10.11 08:01

Einige Anmerkungen dazu:

Wieso speicherst Du das Bild nicht bereits beim Scannen
mit der entsprechenden Auflösung?

Wenn Du diese Code-Variante wählst, verkleinerst Du beim
Neuzeichnen das Bild zugleich - es würde durch die DPI-
Erhöhung sonst vergrößert (Einheit: Pixel), um eine höhere
Info-Menge aufnehmen zu können.
Ich würde im Graphics-Objekt deshalb den Interpolationmode
auf "HighQualityBiCubic" setzen.

Das Speichern einer Bitmap im JPEG-Code führt zum Ersetzen des
Originalbildes durch ein speichersparendes Ersatzbild. Das ist
immer mit einem Verlust an Information verbunden und führt
sehr leicht zu den bekannten JPG-typischen Bildfehlern.
Ich würde deshalb den Qualitäts-Parameter des Net-eigenen
JPEG-Encoders nutzen und den Wert 95 verwenden. (Beispiele
findest Du unter dem Stichwort "EncoderParameters").

MfG
Manfred

Beitrag wurde zuletzt am 25.10.11 um 08:02:22 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 25.10.11 12:43

Vielen Dank für Deine Hilfe
Es ist hier alles, wie immer im Leben, viel komplizierter als ich es dargestellt habe. Es geht um komplette Layouts, die aus diversen, in unterschiedlicher Auflösung gescannten oder am PC gezeichneten Grafiken nebst Text und Grafikelementen bestehen. Diese Software habe ich selbst geschrieben, sodass das Dateiformat dieser Layouts auch nur mit besagter Software bearbeitet und gespeichert werden kann. Es kommt hier darauf an, dass alle Elemente, wenn das Layout aus dem Drucker kommt genau die Größe haben sollen, die ihnen bestimmt ist.
Wenn ich das Layout als eine Bitmap gefertigt habe und diese nach der Umstellung von 96 auf 300 DPI auf die Unterlage male, dann würde sie ohne "Verkleinerung" per Interpolation vergrößert werden, also keine Mehrinformation liefern. Durch die Beschränkung auf oben genanntes Rechteck erhalte ich aber genau wieder die Originalgröße. Dadurch, dass aber nun 300 DPI im Bitmapheader steht, wird beim Ausdruck auf Papier das JPG um genau das Maß an die Grafikumgebung des Kunden angepaßt, dass auf dem Papier das Bild in optimaler Qualität in genau der gewünschten Größe gedruckt wird.
Damit nicht alle meine Kunden auf meine Software angewiesen sind, muß ich diese Layoutseiten als komplette Grafiken so an sie weiterreichen können, dass sie diese auch, ohne besondere Einstellungen zu treffen, mit jedem vernünftigen Bildbearbeitungsprogamm in der "richtigen" Größe ausdrucken können (JPG, damits auch per Email geht (natürlich kann ich auch BMP, Tiff, Gif etc. liefern)).

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Manfred X
Datum: 25.10.11 13:26

Hallo!

Das hatte ich schon verstanden,
Die Einstellung der Interpolationmode-Eigenschaft dient
dazu, um ein optimales Ergebnis bei der Verkleinerung
des Bildes zu erzielen.

Der Standardwert ist "Bilinear".
Dieser Modus ist NICHT dafür geeignet, ein Bild auf mehr als 50
Prozent seiner ursprünglichen Größe zu verkleinern. (VB-Doku!!)

Using g As Graphics = Graphics.FromImage(vorschau1)
   g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
   g.DrawImage(vorschau, 0, 0, vorschau.Width, vorschau.Height)
End Using
Der Qualitäts-Parameter ermöglicht die Ermittlung, bis zu
welchem Grad die Bilddatei verkleinert werden kann, ohne dass
es zu störenden Infoverlusten bzw. Bildfehlern kommt.
(Quality-Werte zwischen 60 und 95 ausprobieren).

Dim EncoderParameters As New Drawing.Imaging.EncoderParameters(1)
EncoderParameters.Param(0) = New Drawing.Imaging.EncoderParameter _
(Drawing.Imaging.Encoder.Quality, Quality)
 
vorschau1.Save(Filename, EncoderInfo("JPEG"), EncoderParameters)
Hilfsfunktion:
Private Function EncoderInfo _
       (ByVal FormatDescriptor As String) As Drawing.Imaging.ImageCodecInfo
 
        ' Formatdescriptoren: BMP JPEG GIF TIFF PNG
 
    Dim i As Integer = 0
    Dim encoders() As Drawing.Imaging.ImageCodecInfo = _
          Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
 
    FormatDescriptor = Trim(UCase(FormatDescriptor))
 
    While i < encoders.Length
       If UCase(encoders(i).FormatDescription) = FormatDescriptor Then
          Return encoders(i)
       End If
       i += 1
    End While
    Return Nothing
 End Function


Beitrag wurde zuletzt am 25.10.11 um 13:39:24 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 25.10.11 16:38

Das ist natürlich ein interessanter Aspekt, ich denke jedoch, dass intern ersteinmal der endgültige Zoomfaktor berechnet wird, wobei dann 1 herauskommt. Das Bild "vorschau" also nicht zuerst der veränderten Auflösung entsprechend vergrößert und dann wieder um den gleichen Betrag verkleinert wird, sondern resultierend gar nichts passiert, außer dass im Bitmapheader jetzt 300 DPI für Resolution steht, was ich ja bezwecke.
Ich habe das mit einem farbigen Bild probiert, es treten selbst nach mehreren Aktionen (hier jetzt natürlich verlustfrei als BMP gespeichert) durch die Anpassung keine sichtbaren Verluste auf. Wenn Du es besser weißt, würde mich das sehr interessieren - einfach nur so - in meinem Fall handelt es sich zu 90% sowieso nur um mehr oder weniger Schwarz-weiß-Grafiken was die Farbe angeht, nicht die Farbtiefe, sodaß etwaige Mißhandlungen nicht so auffallen.

Die Tatsache, dass bei einem endgültigen Abspeichern als JPG Verluste auftreten, ist mir klar. Hast Du eine Ahnung, mit welcher Qualität VB NET ein JPG standardmäßig packt, wenn man es nicht explizit über den ImageEncoder bestimmt - allzu schlecht ist die jedenfalls nicht, wenn auch in der JPEGinfo darüber nichts angezeigt wird.
Ich komme erst nacher dazu, Deine interessante Qualitätsbestimmung auszutesten. Also bis denne!

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Manfred X
Datum: 25.10.11 18:33

Falls die Bitmap-Dateien eine BitmapinfoHeader-Struktur
hinter der BitmapfileHeader-Struktur enthalten, kannst Du
die Auflösung direkt in die Datei eintragen (Filestream).
Neuzeichnen ist dann überflüssig. Das Bild kann geladen
und direkt als JPEG gespeichert werden.
http://en.wikipedia.org/wiki/BMP_file_format

Die Standard-Qualitätsstufe des JPEG-Decoders liegt
bei einem Wert von ca. 80.

Für SW-Graphiken ist das GIF-Format weit besser geeignet,
weil JPEGs in dem Fall gelegentlich hellgraue Quadrate in
weissen Flächen enthalten bzw. dunkelgraue in schwarzen Flächen.

MfG
Manfred

Beitrag wurde zuletzt am 25.10.11 um 18:54:51 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 25.10.11 19:14

Da hast Du recht - mir war nur nicht klar, wo ich die Auflösung eintragen sollte.
Der Wikipediabeitrag is da ja sehr aufschlußreich.
Ich denke 80% Jpeg-Qualität sind doch ganz ansehnlich, da brauche ich nichts zu encoden und wie Du schon sagst Gif is sowieso besser. Das Wichtigste war mir die Sache mit der Auflösung. Da hast Du mir sehr schnell geholfen, vielen Dank nochmal

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Bitmap mit einer bestimmten Auflösung speichern 
Autor: Kalli
Datum: 26.10.11 18:28

Hier nocheinmal der direkte Eintrag der Auflösung in die Bilddatei. Ich schreibe das hier nocheinmal auf, weil mir die Sache doch ein wenig Kopfzebrechen gemacht hat, bis ich mich aus Atari-Tagen daran erinnerte dass bei solchen Sachen manchmal Hi- und Low-Bytes vertauscht sind (ja,ja lacht nur
dim auflösung as Integer = 300
dim pfad as string = "C:\testbild.bmp" 'das ist die Bitmap, die eine neue 
' Auflösung bekommen soll
dim fs as new IO.FileStream(pfad,IO.Filemode.Open) 'Bild für Zugriff öffnen
'Nun kommt ein Trick, der leider nötig ist - Low- und Highbytes vertauschen
dim b() As Byte = BitConverter.GetBytes(CInt(auflösung/0.0254)) 'die Auflösung 
' wird in Pixel pro Meter verlangt
'Jetzt alle vier Bytes in der richtigen Reihenfolge an die richtige Stelle in 
' den Bitmapinfoheader schreiben
fs.Seek (38,0) 'Hier im Header steht die Horizontale Auflösung und vier Bytes 
' weiter die Vertikale (s.Link oben von Manfred X auf Wikipedia)
dim bw As New IO.BinaryWriter(fs)
bw.Write(b,0,4) 'X-Auflösung
bw.Write(b,0,4) 'Y-Auflösung
bw.Close()
fs.Close()
fs.Dispose

Dont debug, because there will allways be one more bug

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel