1

I'm trying to convert a batch of .pngs to .jpgs, as in this question:

For Each file As String In Directory.EnumerateFiles(path).Where(Function(s) s.EndsWith(".png"))
    Dim newfile As String = IO.Path.Combine(newpath, IO.Path.GetFileNameWithoutExtension(file) & ".jpg")
    Using png As Bitmap = Bitmap.FromFile(file)
        Using jpg As New Bitmap(png.Width, png.Height)
            Using g As Graphics = Graphics.FromImage(jpg)
                g.Clear(Color.FromArgb(255, 212, 208, 200))
                g.DrawImageUnscaled(png, 0, 0)
                jpg.Save(newfile, ImageFormat.Jpeg)
            End Using
       End Using
    End Using
Next

The call to jpg.Save, however, with a "generic error" in GDI+. Originally outside of the innermost Using statement, I moved the call inwards as per this answer, but it didn't change anything. I have verified that newfile contains a valid path, and that the program has write access to the directory. What am I missing?

Community
  • 1
  • 1
dlras2
  • 8,416
  • 7
  • 51
  • 90

2 Answers2

0

I know you are saying that you are sure about the file path, but here I can see that newfile you are passing to the IO.Path.Combine have a null value. I just initialize the newfile string with the Path string, and run your code successfully without any problem:

Dim newfile As String = Path
newfile = IO.Path.Combine(newpath, IO.Path.GetFileNameWithoutExtension(file) & ".jpg")
Jalal Said
  • 15,906
  • 7
  • 45
  • 68
  • `newpath` is a constant (different) directory, and is passed to `IO.Path.Combine`, not `newfile`. – dlras2 Jul 28 '11 at 15:47
  • @Dan: I see, the problem then at the `newfile`, trust me. for you to test the code. just replace the `newpath` with `path`, the result is a new `jepg` files will be added in the same directory as the `Path` directory. – Jalal Said Jul 28 '11 at 15:51
  • @Dan: Also note that the `Path.Combine` will behave differently depending on the string to combine. for instance combine `"C:\testing\"` with `"tested\"` will give you a different string than `"C:\testing\"` and `"tested\"`.. the last one will have the `"\"` on the string.. – Jalal Said Jul 28 '11 at 15:58
0

I've tried your code (rewritten in C#) and discovered one thing: the exception occurs only if you try to save the new image inside the same directory from which you are listing the PNGs. If you change the code to write images to a different directory, the code works without problems.

I cannot really give you an explanation of why this is happening (other than perhaps Bitmap.FromFile() is locking up the directory somehow). There are a lot of GDI+ Bitmap quirks.

BTW: I managed to rework my C# code so it doesn't throw exceptions, I'll rewrite your VB snippet in an analogous way (I haven't tested the VB code though):

For Each file As String In Directory.EnumerateFiles(path).Where(Function(s) s.EndsWith(".png"))
    Dim newfile As String = IO.Path.Combine(newpath, IO.Path.GetFileNameWithoutExtension(file) & ".jpg")
    Using jpg As New Bitmap(png.Width, png.Height)
        Using g As Graphics = Graphics.FromImage(jpg)
            Using png As Bitmap = Bitmap.FromFile(file)
                g.Clear(Color.FromArgb(255, 212, 208, 200))
                g.DrawImageUnscaled(png, 0, 0)
            End Using

            jpg.Save(newfile, ImageFormat.Jpeg)
       End Using
    End Using
Next

Hope it works.

Igor Brejc
  • 18,714
  • 13
  • 76
  • 95