1

I need to edit IPTC data to jpgs.

i used this code to read the keywords it already has, but i am not able to write new ones:

IPTC .NET read/write c# library

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Try

        Dim stream = New FileStream(imagepath, FileMode.Open, FileAccess.Read)
        Dim decoder = New JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None)
        Dim metadata = TryCast(decoder.Frames(0).Metadata, BitmapMetadata)
        If metadata IsNot Nothing Then
            Keywords.Text = metadata.Keywords.Aggregate(Function(old, val) Convert.ToString(old) & "; " & Convert.ToString(val))
        End If


    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

any help appreciated! thanks

Community
  • 1
  • 1
user2452250
  • 777
  • 2
  • 11
  • 26

1 Answers1

2
    Dim stream = New FileStream(imagepath, FileMode.Open, FileAccess.Read)
    Dim decoder = New JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None)
    Dim metadata = TryCast(decoder.Frames(0).Metadata, BitmapMetadata)
    If metadata IsNot Nothing Then
        Keywords.Text = metadata.Keywords.Aggregate(Function(old, val) Convert.ToString(old) & "; " & Convert.ToString(val))
    End If
    Dim bitmapFrame = decoder.Frames(0)
    metadata = bitmapFrame.Metadata.Clone()
    metadata.Keywords = New ReadOnlyCollection(Of String)(New List(Of String)(New String() {"test1", "test2"}))
    Dim stream1 = New FileStream(imagepath1, FileMode.Create)
    Dim encoder = New JpegBitmapEncoder()
    encoder.Frames.Add(bitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts))
    encoder.Save(stream1)

UPDATE New code replaces an image.

Imports System.Windows.Media.Imaging
Imports System.IO
Imports System.Collections.ObjectModel
Class MainWindow
    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
        Dim imagepath = ".\img.jpg" ' path to file
        Dim stream = New FileStream(imagepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        Dim decoder = New JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None)
        Dim metadata = TryCast(decoder.Frames(0).Metadata, BitmapMetadata)
        If metadata IsNot Nothing Then
            Keywords.Text = metadata.Keywords.Aggregate(Function(old, val) Convert.ToString(old) & "; " & Convert.ToString(val))
        End If
        Description.Text = metadata.GetQuery("/app13/irb/8bimiptc/iptc/Caption") 'get description
        Dim bitmapFrame = decoder.Frames(0)
        metadata = bitmapFrame.Metadata.Clone()
        Dim newkeywords As New List(Of String)(New String() {"test1", "test2"})
        newkeywords.AddRange(metadata.Keywords) ' this strin adds old keywords
        metadata.Keywords = New ReadOnlyCollection(Of String)(newkeywords) 'replace keywords
        metadata.SetQuery("/app13/irb/8bimiptc/iptc/Caption", "My test picture1.") ' set new description
        Dim memstream As New MemoryStream() ' create temp storage in memory
        Dim encoder = New JpegBitmapEncoder()
        encoder.Frames.Add(bitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts))
        encoder.Save(memstream) ' save in memory
        stream.Close()
        stream = New FileStream(imagepath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)
        memstream.Seek(0, System.IO.SeekOrigin.Begin) ' go to stream start
        Dim bytes(memstream.Length) As Byte
        memstream.Read(bytes, 0, memstream.Length)
        stream.Write(bytes, 0, bytes.Length)
        stream.Close()
        memstream.Close()
    End Sub
End Class

jpeg metadata here.
IPTC fields here.

Dima Kurilo
  • 2,206
  • 1
  • 21
  • 27
  • 1
    maybe if you'd explain your code a bit it would help the OP a bit more and help him to learn... good job by the way! – sharkyenergy Aug 13 '13 at 06:34
  • @sharkyenergy, JpegBitmapDecoder doesn't write a file. It reads and decodes a file to in memory bitmap them. If you need to save a file, you can create JpegBitmapEncoder and save an image with modified keywords. – Dima Kurilo Aug 13 '13 at 08:46
  • 2
    sorry i think i dont understand you now. the OP is asking for a way to write (i suppose add) new keywords to an existing file. for example , he has a picture of a house and would like to add the keywords house, garden, door, window etc. to the file. is that what your posted code does? what do you mean that it doesnt write a file? – sharkyenergy Aug 13 '13 at 10:52
  • Adding new keywords = replace file. I changed my answer. – Dima Kurilo Aug 13 '13 at 15:55
  • thanks! sharkyenergy was right. dmitry i check your code asap! will let you know Tomorrow if it is ok for my use. – sharkyenergy Aug 13 '13 at 20:58
  • thanks, but i am having problems with the second part. the part that saves the file. i keep getting the message that the file is used by another process.. any idea why? – sharkyenergy Aug 14 '13 at 18:05
  • fixed, thanks! now its working! one minor thing, this ADDS keywords to the existing ones. what if i would like to REPLACE the existing ones? thanks! – sharkyenergy Aug 14 '13 at 18:25
  • 1
    ok. I've just begun to think about the previous problem. :) Just delete this string: newkeywords.AddRange(metadata.Keywords) – Dima Kurilo Aug 14 '13 at 18:29
  • yayyyyyy it worksss! thank you sooo much! +50 is for you! youre great! what if i would like to edit other iptc data too? could you please update the code with also another additional value? like the description for example? thanks!! – sharkyenergy Aug 14 '13 at 19:07
  • 1
    I added some information about metadata and lines that read and write metadata. – Dima Kurilo Aug 14 '13 at 20:17
  • Hi dmitry! your code doesnt seem to save empty keywords. what if i want to delete all keywords from a file? thanks! – sharkyenergy Aug 25 '13 at 11:43
  • Dmitry sorry for stressing, i have been trying for the last 4 hours without success.. if i delete every keyword i cant save the file.. it keeps the old keywords.. what can i do? – sharkyenergy Aug 25 '13 at 15:47
  • 1
    @Justme, sorry. I was busy. Set lines: Dim newkeywords As New List(Of String)(New String() {"test1", "test2"}) as Dim newkeywords As New List(Of String)({""}) and delete newkeywords.AddRange(metadata.Keywords) ' this strin adds old keywords – Dima Kurilo Aug 25 '13 at 17:13
  • thank you very much. it was so simple! i tried literally everything except this! THanks thanks thanks – sharkyenergy Aug 25 '13 at 19:13
  • dimitry i see "thumbnail" in the links you provided. does that mean that i can access a small thumbnail of each jpg? – sharkyenergy Aug 25 '13 at 19:53
  • 1
    Shure. But I don't test it with System.Windows.Media.Imaging. – Dima Kurilo Aug 25 '13 at 20:05
  • Cool! would you have the time to answer the question how to use it if i post it? You seem to be the only expert on this around the web! – sharkyenergy Aug 25 '13 at 20:28
  • http://stackoverflow.com/questions/18433854/how-can-thumnails-in-jpg-meta-data-be-accessed i posted the question here. THANK YOU! – sharkyenergy Aug 25 '13 at 21:23
  • had to repost it here: http://stackoverflow.com/questions/18442901/display-metadata-thumbnail-of-jpeg-in-picturebox sorry – sharkyenergy Aug 26 '13 at 11:21
  • 1
    @sharkyenergy, I answered to your question. I think, many people here can work with image. But It doesn't interest them. – Dima Kurilo Aug 26 '13 at 14:36
  • hi dmitry! after a month now i got reports from users that if there are many keywords they get the error message `The image data generated an overflow during processing` i tried googeling it but didnt find what is causing it. do you have an idea? only thing i found is that appearently some sort of "space" in the file runs out and it has to be reencoded. is that true? if so how can that be done? – sharkyenergy Oct 08 '13 at 12:34
  • @sharkyenergy, I'm suggest to move this discussion to email (dima@kurilo.su) or Skype (DKurilo). And then we can write result of discussion here. – Dima Kurilo Oct 09 '13 at 19:24
  • Hi Dmirty, i found a little bug on my code that was really stupid.. now it works! thank you and sorry for bothering! if you dont mind i keep your email address.. – sharkyenergy Oct 10 '13 at 04:54