# Tool to convert Textures to power of two?

I'm currently porting a game to a new platform, the problem being that the old platform accepted non power of two textures and this new platform doesn't.

To add to the headache, the new platform has much less memory so we want to use the tools provided by the vendor to compress them; which of course only takes power of two textures.

The current workflow is to convert the non power of tho textures to dds with 'texconv', then use the vendors compression tools in a batch.

So, does anyone know of a tool to convert textures to their nearest 'power of two' counterparts?

Thanks

• Can you send me the batchfile please ? – user14224 Mar 8 '12 at 22:13
• Sample: convert OUT.jpg -format "%[fx:2^(ceil(log(w)/log(2)))/2]" info: Will return lower pot – Dawid Drozd Jan 10 '16 at 17:47

You might check out this ImageMagick forum post where someone goes into detail on power of two rescaling via some extended features of ImageMagick.

• I recommend ImageMagick too, because it's controlled from the command-line so you can write a batch script to convert all your images. Depending on your needs you might not want to rescale the images however; I would think a better approach is to simply add empty pixels to the edges to fill out the power-of-two dimensions. – jhocking Jun 1 '11 at 16:24
• Yeah thats what I'm looking to do, I'll check it out tomorrow, thanks! – Jonathan Connell Jun 2 '11 at 19:02

So I checked out ImageMagick, it wasn't really for me, so I ended up using TheGimp's Script-Fu to first off write a batch procedure to convert all files in a folder to the nearest (bigger) power of two, and optionally scale the image down afterwards if it is too big. This is a simplified version (I can give anyone the batch if needed).

(define
(script-fu-resize-upper-pot image drawable)
(let*
(
;; Store upper power of two for height and width of image
(height (pow 2 (ceiling (/ (log (car (gimp-image-height image))) (log 2)))))
(width (pow 2 (ceiling (/ (log (car (gimp-image-width image))) (log 2)))))
)

;; Resize the Image
(gimp-image-resize image width height 0 0)
)
)


Of course the big problem with this is that the Script-Fu command file-glob only allows you to cycle through one folder, and you have to use a very ugly batch call for it to work :

"c:\Program Files\GIMP-2.0\bin\gimp-2.6.exe" -i -b "(script-fu-resize-upper-pot-batch \"C:\\ImageData\\*.png\" 0) (gimp-quit 0)"


So the next problem was to iterate through the folders to call the gimp script on all of them, after a bit of testing, I found this PowerShell script :

Clear-Host
$Directory = "C:\PuddleSqData\"$Dirs = Get-ChildItem -path $Directory -recurse -include * | where {$_.PsIsContainer}

$Gimp = "gimp-console-2.6.exe" foreach($Dir in $Dirs) {$SourcePath = $Dir.FullName$GimpifiedSourcePath = $SourcePath -replace("\\", "\\")$GimpParams = @("-i", "-b", ""(script-fu-resize-upper-pot-batch \"$GimpifiedSourcePath\\*.png\" 0)"", "-b", ""(gimp-quit 0)"") Write "Calling$GIMP $GimpParams"$p = [diagnostics.process]::Start($Gimp,$GimpParams)
\$p.WaitForExit()
}


And everything is now working! I guess that maybe ImageMagick would have been a better solution, it's just a shame that TheGimp proposes a batching process that really isn't powerful enough.

Hope this helps someone!

I use Sprite Sheet Packer to put multiple textures into a single power-of-two-texture. This also generates either a text file or an xml file with information on the source rectangle of all the sprites in this power-of-two-texture.

• I may not have made it clear enough in my question, but as I was porting a game, the idea was to have to change the least amount of existing code/assets as possible. If I had packed all the textures into a bigger texture, all texture references and UV's would have had to have been re-done. – Jonathan Connell Jun 29 '11 at 9:34
• Scaling textures would not work for 2D games as sprites would need different scaling and that is why I used my approach while porting. Obviously you are porting a 3D game.. :-) – Wouter Jun 29 '11 at 9:39
• It is actually a 2D game with textures on 2D billboards :). In the level editor only the top-left position of the texture is remembered, and the quad and scaling are calculated at load time with basic pre-set UV's. So quite a specific case, I must admit. – Jonathan Connell Jun 29 '11 at 9:43

I had some errors when running Jonathan's script so here's my modified version:

(define (script-fu-resize-upper-pot pattern)
(let* ((filelist (cadr (file-glob pattern 1))))
(while (not (null? filelist))
(let* ((filename (car filelist))
(image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
(drawable (car (gimp-image-get-active-layer image))))
(let*
(
;; Store upper power of two for height and width of image
(height (pow 2 (ceiling (/ (log (car (gimp-image-height image))) (log 2)))))
(width (pow 2 (ceiling (/ (log (car (gimp-image-width image))) (log 2)))))
)
(gimp-message filename)
(gimp-image-scale-full image width height INTERPOLATION-CUBIC))
(gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
(gimp-image-delete image))
(set! filelist (cdr filelist)))))


I am running Gimp 2.8 on Windows 8. Here are the steps to run it:

1. Save the code above to a script named: C:\Program Files\GIMP 2\share\gimp\2.0\scripts\script-fu-resize-upper-pot.scm
2. Run the following command substituting the Gimp version, path and extension to your image files as appropriate. Note: this script does not recursively process sub-folders.

C:\Users\Myself>"c:\Program Files\GIMP 2\bin\gimp-2.8.exe" -i -b "(script-fu-resize-upper-pot \"R:\\Dev\\unity\\UnityGame\\Assets\\Textures\\*.jpg\" 0)"