Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Converting iPhone iOS '.cpbitmap' images to PNGs
from PIL import Image,ImageOps
import struct
import sys
if len(sys.argv) < 3:
print "Need two args: source_filename and result_filename\n";
filename = sys.argv[1]
result_filename = sys.argv[2]
with open(filename) as f:
contents =
unk1, width, height, unk2, unk3, unk4 = struct.unpack('<6i', contents[-24:])
im = Image.frombytes('RGBA', (width,height), contents, 'raw', 'RGBA', 0, 1)
r,g,b,a = im.split()
im = Image.merge('RGBA', (b,g,r,a))

This comment has been minimized.

Copy link
Owner Author

danielsharvey commented May 28, 2017

Converting iPhone iOS '.cpbitmap' images to PNGs



This comment has been minimized.

Copy link

sh00tg0a1 commented Feb 19, 2019

It doesn't work for wallpaper in iOS 12, because every line has an offset on the basis of 16 bytes.

See the same stack overflow thread, but on the lower part - the JS solution.

My code works for the backup of iOS 12

from PIL import Image
import sys
import math
import struct

def r8(f):
    c = ord(
    return c

if len(sys.argv) <= 2:
    print("Usage: %s <input> <output>" % sys.argv[0])
    f = open(sys.argv[1], "rb"), 2)
    magic =
    print magic
    if magic != "bplist00":
        print("Didn't find bplist header, are you sure this is a cpbitmap file?")
        exit(1), 1)
    dat =
    width, height = struct.unpack("<HxxH", dat)
    print("Size: %dx%d" % (width, height))
    img ="RGBA", (width, height))
    imgd = img.load()

    # Take case of the line size
    line_size = int(math.ceil(width/16.0) * 16)
    print line_size
    for y in range(height):
        for x in range(width):
            b, g, r, a = r8(f), r8(f), r8(f), r8(f)
            imgd[x, y] = (r, g, b, a) - width)*4, 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.