Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Converting iPhone iOS '.cpbitmap' images to PNGs
#!/usr/bin/python
from PIL import Image,ImageOps
import struct
import sys
if len(sys.argv) < 3:
print "Need two args: source_filename and result_filename\n";
sys.exit(0)
filename = sys.argv[1]
result_filename = sys.argv[2]
with open(filename) as f:
contents = f.read()
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))
im.save(result_filename)
@danielsharvey

This comment has been minimized.

Copy link
Owner Author

@danielsharvey danielsharvey commented May 28, 2017

Converting iPhone iOS '.cpbitmap' images to PNGs

See https://stackoverflow.com/a/44225159/5219886

@sh00tg0a1

This comment has been minimized.

Copy link

@sh00tg0a1 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.
https://stackoverflow.com/questions/7998324/dot-cpbitmap-images-imgaename-cpbitmap

My code works for the backup of iOS 12

from PIL import Image
import sys
import math
import struct

def r8(f):
    c = ord(f.read(1))
    return c

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

    f.seek(0)
    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)
        f.seek((line_size - width)*4, 1)

    f.close()
    img.save(sys.argv[2])
@donly

This comment has been minimized.

Copy link

@donly donly commented Aug 3, 2020

@sh00tg0a1 not working with this message:

import: delegate library support not built-in '' (X11) @ error/import.c/ImportImageCommand/1282.
./cpbitmap.py: line 6: syntax error near unexpected token `('
./cpbitmap.py: line 6: `def r8(f):'
@weedy

This comment has been minimized.

Copy link

@weedy weedy commented Sep 13, 2020

Looks like iOS 13 broke all of these.

Also needs to be converted to python3/PIL7. Thankfully I have a iOS12 backup still and gentoo gives me every python/PIL combo I could ever want.

@sh00tg0a1

This comment has been minimized.

Copy link

@sh00tg0a1 sh00tg0a1 commented Sep 24, 2020

@donly @weedy
I have updated the code. It is compatible with python3/PIL now. You can find the code here
.

@danielsharvey

This comment has been minimized.

Copy link
Owner Author

@danielsharvey danielsharvey commented Sep 24, 2020

@sh00tg0a1 Thanks

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.