Exported PNG image looks scrambled when generated by CGWindowListCreateImage/PNGCanvas
Asked Answered
P

0

1

I've got this Python code:

import Quartz.CoreGraphics as cg
region = cg.CGRectMake(0, 0, 100, 100) # You can also use cg.CGRectInfinite for the full screen.
image = cg.CGWindowListCreateImage(region, cg.kCGWindowListOptionOnScreenOnly, cg.kCGNullWindowID, cg.kCGWindowImageDefault)
prov = cg.CGImageGetDataProvider(image)
img_data = cg.CGDataProviderCopyData(prov)
img_width, img_height = cg.CGImageGetWidth(image), cg.CGImageGetHeight(image)

from pngcanvas import PNGCanvas
import struct
canvas = PNGCanvas(img_width, img_height)
for x in range(img_width):
    for y in range(img_height):
        # Calculate offset, based on http://www.markj.net/iphone-uiimage-pixel-color/
        offset = 4 * ((img_width * int(round(y))) + int(round(x)))
        # Pixel data is unsigned char (8bit unsigned integer), and there are for (blue,green,red,alpha).
        # Unpack data from string into Python'y integers.
        b, g, r, a = struct.unpack_from("BBBB", img_data, offset=offset)
        # Assign BGRA color as RGBA.
        canvas.point(x, y, color = (r, g, b, a))

with open("test.png", "wb") as f:
    f.write(canvas.dump())

And it seems to work, apart of the fact that the saved PNG image looks scrambled:

CGWindowListCreateImage, PNGCanvas, scrambled png image

The code logic is based on the code from this post (see: pixel function). I don't see any issues with the code above. What I am missing?

Pimentel answered 29/5, 2017 at 20:9 Comment(4)
The example script from the post you've linked suffers the same issue when setting CGRectMake(0, 0, 100, 100). I haven't tried it, although I'm guessing if you changed your code to CGRectMake(0, 0, 400, 400) it wouldn't be scrambled...Smart
@l'L'l You're right, 400x400 works fine.Pimentel
I believe the problem is within the way the offset is calculated, or the way the values are unpacked.Smart
After looking at this a bit more I noticed that the image size must be a multiple of 16, so basically 16x16, 32x32, 48x48, 64x64, etc. only seem to work...Smart

© 2022 - 2024 — McMap. All rights reserved.