Is there any library able to encode image data to ASTC texture on demand? I am aware it is CPU intensive, but interested anyway.
3 Answers
import ImageIO
import MetalKit
let loader: MTKTextureLoader
let srcImage: CGImage
let ktxData = NSMutableData()
let dest = CGImageDestinationCreateWithData(ktxData, "org.khronos.ktx" as CFString, 1, nil)!
CGImageDestinationAddImage(dest, srcImage, 0, ["kCGImagePropertyASTCBlockSize": 0x88] as CFDictionary)
CGImageDestinationFinalize(dest)
try loader.newTexture(data: ktxData as Data, options: [])
The kCGImagePropertyASTCBlockSize
option shown gets you 8x8 block size (ie. 2 bits per pixel); the only other allowed size is 4x4 (8 bits per pixel), which is the default.
For max performance, add kCGImageDestinationLossyCompressionQuality: 0.0
to the options for CGImageDestinationAddImageFromSource
.
Other possible flags are kCGImagePropertyASTCUseLZFSE
, kCGImagePropertyASTCPreTwiddle
, kCGImagePropertyASTCFlipVertically
and kCGImagePropertyASTCWeightChannelsEqually
(all bools).

- 189
- 2
- 2
-
1this is fantastic! – Volodymyr B. Aug 03 '18 at 10:02
-
This looks like undocumented way because I can not find `kCGImagePropertyASTCBlockSize` in documentation as well as `org.khronos.ktx` UTI. – John Tracid Aug 15 '20 at 14:44
-
The ASTC compression is documented in Apple header files here https://github.com/JamieBerghmans/Cylinder-iOS13/blob/master/deps/iPhoneOS13.2.sdk/usr/include/AppleTextureEncoder.h#L49 – Troy Nov 26 '21 at 07:03
In iOS 10, Apple added ASTC encoding to the system. You can access it either through /usr/include/AppleTextureEncoder.h, /usr/lib/libate.dylib or (simpler) just encode to ASTC using the usual image encoding utils available through CG / ImageIO.framework. See CGImageDestination and associated objects. One can also get to it through image asset catalog compression in Xcode.
The system ASTC encoder is much faster than the ARM reference encoder. Block sizes 4x4 and 8x8 are supported. Performance should be similar to JPEG or PNG encoding.

- 1,592
- 9
- 16
-
I got it working with CGImageDestination, but how to set 8x8 block size? – Volodymyr B. Mar 26 '18 at 16:59
-
https://github.com/ARM-software/astc-encoder is the reference compressor (created by ARM and AMD). It is probably not hard to get the source code working on an iOS device. It might be prohibitively slow, but it does offer various speed options so maybe one will strike the right balance between quality and speed for you.

- 6,648
- 4
- 19
- 30
-
I'm thinking of put into a long running background task when user is out of the app. It could gradually swap uncompressed textures to ASTC over time. – Geri Borbás Feb 21 '17 at 18:22
-
Aw, seems I cannot use this directly: "This confidential and proprietary software may be used only as authorised by a licensing agreement from ARM Limited (C) COPYRIGHT 2011-2012 ARM Limited. ALL RIGHTS RESERVED." – Geri Borbás Feb 21 '17 at 18:30
-
I think your authorisation is here: https://github.com/ARM-software/astc-encoder/blob/master/license.txt. It isn't a standard license, it looks to me at a quick glance as if it's permissive, similar to zlib/mit, but IANAL so do read carefully. – Columbo Feb 21 '17 at 18:36
-
I'll reach out to them directly if I come to implement this, thanks! – Geri Borbás Feb 21 '17 at 18:39