Announcement

Collapse
No announcement yet.

RAW-Dateien in Bitmap laden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • RAW-Dateien in Bitmap laden

    Moin!

    Ich glaube ich werde langsam alt :-(

    Ich habe jahrelang ein selbst geschriebenes Progrämmchen benutzt, dass unter anderem folgendes enthält:

    [highlight=vbnet]Dim _image As Bitmap
    _image = New Bitmap(file.FullName)[/highlight]

    Wobei File waschechte Nikon Kamera RAW-Dateien waren. Danach habe ich dann aus den PropertyItems ein paar EXIF-Daten gelesen und _image wieder disposed.

    Ähhm, peinlich aber wahr: Als einer der letzten Mohikaner wollte ich endlich von XPSP3 mit VS2008 auf W7-64 mit VS2010 umsteigen und siehe da: Unter VS2010 mit NET4 kann ich plötzlich keine NEF-RAW-Dateien in eine Bitmap laden. Weiß der Geier wieso. Vermutlich fehlt mir nur eine DLL oder so. Nur kann ich mich überhaupt nicht mehr erinnern wie ich das damals hinbekommen habe.

    Welcher Pfadfinder hilft mir alten Mann über die Straße?

    PS. Das aktuelle 90MB fette Nikon Codec ist installiert. Fragt sich nur wozu das alles gut ist.
    Zuletzt editiert von Uwe-W; 13.12.2011, 12:49.

  • #2
    Kann es sein das hier .NET nur die Funktionalität des OS verwendet und hier einfach die nötige Unterstützung auf unterster ebene einfach nicht mehr installiert ist?

    Comment


    • #3
      Durchaus möglich. Ich kann mir eigentlich auch nicht vorstellen, das NET4 eine Fähigkeit aus NET2 nicht mehr besitzt. Was bedeuten könnte, dass mir noch ein Teil des Unterbaus fehlt und ich hier eigentlich im falschen Forum bin :-)

      Wenn du recht hast, dann gibt es zumindest für 32Bit-Windows so etwas und ich hatte es unter XP installiert. Schließlich habe ich mit der o.g. Funktion etwa 80.000 NEFs gelesen ...

      Wer kennt eine Liste der von NET4 nativ unterstützen Dateiformate für GDI+?
      Wer kennt eine Bibliothek die GDI+ die Unterstützung von Nikon-NEFs (und anderen RAW-Formaten) liefert?

      Comment


      • #4
        Es ist wohl tatsächlich so, das W7 eine undokumentierte Funktionalität von XP verloren hat:

        http://social.msdn.microsoft.com/For...7-5e98a09da97a

        Also kann ich wohl nur ein externes Tool (z.B. Exiftool) bemühen, auf WPF umsteigen, oder zu XP zurückgehen. Das sind alles keine verlockenden Aussichten :-(

        Immerhin bin ich wohl doch noch nicht so alt, war aber dumm genug, jahrelang ein undokumentiertes Feature von XP genutzt zu haben. Immerhin hat es etwa 180.000 mal gut funktioniert. :-)

        Wenn noch jemand eine gute Idee hat, wäre ich sehr dankbar.

        Comment


        • #5
          Du hast das in deinem Link angesprochene 'Microsoft Camera Codec Pack' ausprobiert?

          Comment


          • #6
            Vielleicht solltest Du mal etwas mehr von Deinem Code preisgeben. Was wird vor diesen beiden Codezeilen gemacht? Wo kommt "file" her?

            Hast Du in dem Programm alle Exceptions sauber abgefangen, ohne eine Fehlermeldung weiterzugeben? Vielleicht wird irgendwo eine DLL benötigt, aber nicht gefunden, und die Exception verrät Dir das nicht?
            Günther

            Comment


            • #7
              Das "'Microsoft Camera Codec Pack" rüstet die Funktion leider nicht nach.

              Anders als im o.g. Thread wird bei mir keine "Out of memory" Exception, sondern eine "Ungültiger Parameter." ArgumentException ausgelöst. Wobei die Datei natürlich existiert, gültig ist und der User alle Zugriffsrechte besitzt. Mit JPGs tritt der Fehler nicht auf.

              Vor diesem Fehler treten im Programm keine Exceptions auf. Der Code ist banal bis peinlich, hat aber jahrelang gut funktioniert:

              [highlight=vbnet]
              Private Function getDate(ByVal file As IO.FileInfo) As DateTime
              If cfg.UseExifDate Then
              ' EXIF-DATETIME aus den EXIF-Daten übernehmen
              Dim _value As String = ""
              Dim _image As Bitmap
              _image = New Bitmap(file.FullName)
              Dim n As Integer
              For n = 0 To _image.PropertyIdList.Length - 1
              If _image.PropertyIdList(n) = 306 Then Exit For 'Metadaten EXIF-DATETIME
              Next
              If n <> _image.PropertyIdList.Length Then
              For i = 0 To _image.PropertyItems(n).Len - 1
              _value = _value & Chr(_image.PropertyItems(n).Value(i))
              Next
              _value = Replace(Strings.Left(_value, 11), ":", ".") & Strings.Right(_value, 9)
              Return CDate(_value)
              End If
              _image.Dispose()
              Else
              ' Änderungsdatum aus dem Dateisystem übernehmen
              Dim _date As DateTime
              _date = file.LastWriteTime
              Return _date
              End If
              End Function
              [/highlight]

              Wie schon geschrieben, tritt der Fehler bei "_image = New Bitmap(file.FullName)" auf. File stammt letztlich aus einer System.IO.Directory.getFiles Methode. Der ganze "For" und "If"-Kram scheint notwendig, da die Metadaten in der Bitmap als Array of Char gespeichert sind.

              Für den Fall das dass auch von Belang ist: Die Funktion wird in einem Backgroundworker aufgerufen der sämtlichen im Dialog gemachten Einstellungen in cfg übergeben bekommen hat.

              PS. Wie quotet man hier ohne die TABs im Source zu verlieren?
              Zuletzt editiert von Uwe-W; 13.12.2011, 12:49.

              Comment


              • #8
                Originally posted by Uwe-W View Post
                PS. Wie quotet man hier ohne die TABs im Source zu verlieren?
                Code als Code (#-Symbol) und nicht als Zitat.


                Nicht "direkt antworten" sondern "antworten", dann kommt ein anderer Editor - warum eigentlich?
                Günther

                Comment


                • #9
                  Hab's geändert. Aber obwohl "[/CODE]" direkt hinter "End Function" steht, enthält der Code-Block am Ende ein ganze Reihe leerer Zeilen die ich so nicht wollte. Ansonsten ist das hier eine nette Forum-SW! (Nicht das mir hier jemand vorwirft, ich würde mich nicht bemühen ordentliche Beiträge zu schreiben :-)
                  Zuletzt editiert von Uwe-W; 12.12.2011, 12:18.

                  Comment


                  • #10
                    Solved!

                    Ich habe eine Lösung für mein Problemchen gefunden die vielleicht anderen weiter hilft:

                    Zunächst wird ein Verweis auf "Presentationcore.dll" aus dem Net Framework 4 zum Projekt hinzugefügt. Dann braucht man nur noch folgenden Sermon:

                    [highlight=vbnet]
                    Imports System.IO
                    Imports System.Windows.Media.Imaging
                    Imports System.Windows.Media

                    Private Function getDate(ByVal file As IO.FileInfo) As DateTime
                    If _cfg.UseExifDate Then
                    ' EXIF-DATETIME aus den EXIF-Daten übernehmen
                    Dim value As String = ""
                    Try
                    Using fileStream As Stream = file.Open(FileMode.Open)
                    Dim _bd As BitmapDecoder = BitmapDecoder.Create(fileStream, _
                    BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
                    Dim _bmd As BitmapMetadata = TryCast(_bd.Frames(0).Metadata, BitmapMetadata)
                    value = _bmd.GetQuery("/ifd/{ushort=306}").ToString
                    value = Replace(Strings.Left(value, 11), ":", ".") & Strings.Right(value, 9)
                    Return CDate(value)
                    End Using
                    Catch
                    ' aus irgendeinem Grund konnte EXIF-DATETIME nicht gelesen werden
                    ' ersatzweise wird das Änderungsdatum aus dem Dateisystem zurück gegeben
                    Return file.LastWriteTime
                    End Try
                    Else
                    ' Änderungsdatum aus dem Dateisystem übernehmen
                    Return file.LastWriteTime
                    End If
                    End Function [/highlight]

                    Diese Funktion holt nur EXIF-DateTime aus den Metadaten. Der ganze Rest wird völlig ignoriert.

                    Wer mehr braucht kann es hiermit versuchen:

                    [highlight=vbnet]
                    Private Class RawMetadataItem
                    Public location As [String]
                    Public value As [Object]
                    End Class

                    Private Property RawMetadataItems() As List(Of RawMetadataItem)
                    Get
                    Return m_RawMetadataItems
                    End Get
                    Set(value As List(Of RawMetadataItem))
                    m_RawMetadataItems = value
                    End Set
                    End Property

                    Private m_RawMetadataItems As List(Of RawMetadataItem)

                    Private Function CaptureMetadata(imageMetadata As ImageMetadata, query As String, _
                    RawMetadataItems As List(Of RawMetadataItem)) _
                    As List(Of RawMetadataItem)
                    Dim bitmapMetadata As BitmapMetadata = TryCast(imageMetadata, BitmapMetadata)
                    If bitmapMetadata IsNot Nothing Then
                    For Each relativeQuery As String In bitmapMetadata
                    Try
                    Dim metadataQueryReader As Object = bitmapMetadata.GetQuery(relativeQuery)
                    Dim metadataItem As New RawMetadataItem()
                    metadataItem.location = query
                    metadataItem.value = metadataQueryReader
                    RawMetadataItems.Add(metadataItem)
                    Dim innerBitmapMetadata As BitmapMetadata = TryCast(metadataQueryReader, BitmapMetadata)
                    If innerBitmapMetadata IsNot Nothing Then
                    RawMetadataItems = CaptureMetadata(innerBitmapMetadata, query, RawMetadataItems)
                    End If
                    Catch
                    ' Irgendwas ist faul
                    ' Hier muß noch ein bischen Grips rein
                    End Try
                    Next
                    End If
                    Return RawMetadataItems
                    End Function

                    Private Function getMetaData(ByVal file As IO.FileInfo) As List(Of RawMetadataItem)
                    Dim RawMetadataItems = New List(Of RawMetadataItem)()
                    Using fileStream As Stream = file.Open(FileMode.Open)
                    Dim decoder As BitmapDecoder = BitmapDecoder.Create(fileStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
                    RawMetadataItems = CaptureMetadata(decoder.Frames(0).Metadata, String.Empty, RawMetadataItems)
                    End Using
                    Return RawMetadataItems
                    End Function [/highlight]

                    getMetaDate holt (hoffentlich) alle lesbaren Metadaten aus der Datei. Ich hab's noch nicht lang und breit getestet.

                    Danke für eure Tipps!
                    Zuletzt editiert von Uwe-W; 13.12.2011, 12:53.

                    Comment

                    Working...
                    X