0
$\begingroup$

I need to import a bunch of models which use .dds textures, which are not supported by Cycles, but they are supported by Blender. I can open such a .dds in the image editor, and press F3(Save image as) to save it as a perfectly functional .png file.

However when I try to do this through Python, it fails without a useful error message, and no new file gets created.

Here is my code:

# Set current panel to Image/UV Editor
area = bpy.context.area
area.type = 'IMAGE_EDITOR'

for i in bpy.data.images:
    area.spaces.active.image = i
    newPath = i.filepath.replace("dds", "png")
    bpy.ops.image.save_as(save_as_render=False, filepath=newPath, relative_path=True)

Which will throw this useless error:

Couldn't save picture.
D:\Path\FileName.png: No error
Error: Could not write image: No error
Traceback (most recent call last):
  File "D:\ProjectPath\TexConvertTest.blend\Text", line 19, in <module>
  File "C:\3D\Blender\blender-2.79-windows64\2.79\scripts\modules\bpy\ops.py", line 189, in __call__
    ret = op_call(self.idname_py(), None, kw)
RuntimeError: Error: Could not write image: No error

I tried running it with admin priviliges, but no difference. Any other suggestions would be appreciated!

$\endgroup$
1
  • $\begingroup$ Have you checked if i.filepath contains something useful? RenderResult and other internal images do not have any filepath, which has to be filtered out. Otherwise add a print statement to identify what image it fails on. $\endgroup$
    – J. Bakker
    Jan 15, 2018 at 7:40

1 Answer 1

2
$\begingroup$

Don't use operators unless there is no other way. In this case you're making your life overly complicated with them. This is my proposed approach:

for i in bpy.data.images:
    new_path = i.filepath.replace(".dds", ".png")
    if new_path == i.filepath:
        print('Refusing to overwrite %s (name=%r)' % (i.filepath, i.name))
        continue
    i.save_render(bpy.path.abspath(new_path))

I've also taken the liberty to change a bit more:

  • Replacing .dds instead of just dds. You don't want to change adds-liquid.dds into apng-liquid.png. For more reliable manipulating of file paths I would recommend pathlib rather than string manipulation.
  • Using bpy.path.abspath() to convert any blendfile-relative file path to an absolute path. Without this, saving the file won't work reliably.
  • Added a check to prevent overwriting a non-DDS file.
  • Applied PEP 8 -- Style Guide for Python Code to your variable names.
$\endgroup$
1
  • 1
    $\begingroup$ Works like a charm, thank you so much! Both for the solution and the great advice. $\endgroup$
    – Mets
    Jan 15, 2018 at 16:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .