Skip to content

Commit 0500bf7

Browse files
committed
Merge pull request kivy#2661 from inclement/sdl2-screenshot
Sdl2 screenshot implemented with glReadPixels
2 parents 6bc03f0 + 124f3ee commit 0500bf7

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

kivy/core/window/_window_sdl2.pyx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
include "../../../kivy/lib/sdl2.pxi"
22

3+
from libc.string cimport memcpy
4+
35
cdef class _WindowSDL2Storage:
46
cdef SDL_Window *win
57
cdef SDL_GLContext ctx
@@ -247,4 +249,43 @@ cdef class _WindowSDL2Storage:
247249
def flip(self):
248250
SDL_GL_SwapWindow(self.win)
249251

252+
def save_bytes_in_png(self, filename, data, int width, int height):
253+
254+
cdef SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(
255+
<char *>data, width, height, 24, width*3,
256+
0x0000ff, 0x00ff00, 0xff0000, 0)
257+
cdef bytes bytes_filename = <bytes>filename.encode('utf-8')
258+
cdef char *real_filename = <char *>bytes_filename
259+
260+
cdef SDL_Surface *flipped_surface = flipVert(surface)
261+
IMG_SavePNG(flipped_surface, real_filename)
262+
263+
264+
265+
# Based on the example at
266+
# http://content.gpwiki.org/index.php/OpenGL:Tutorials:Taking_a_Screenshot
267+
cdef SDL_Surface* flipVert(SDL_Surface* sfc):
268+
cdef SDL_Surface* result = SDL_CreateRGBSurface(
269+
sfc.flags, sfc.w, sfc.h, sfc.format.BytesPerPixel * 8,
270+
sfc.format.Rmask, sfc.format.Gmask, sfc.format.Bmask,
271+
sfc.format.Amask)
272+
273+
274+
cdef Uint8* pixels = <Uint8*>sfc.pixels
275+
cdef Uint8* rpixels = <Uint8*>result.pixels
276+
277+
cdef tuple output = (<int>sfc.w, <int>sfc.h, <int>sfc.format.BytesPerPixel,
278+
<int>sfc.pitch)
279+
print(output)
280+
281+
cdef Uint32 pitch = sfc.pitch
282+
cdef Uint32 pxlength = pitch*sfc.h
283+
284+
cdef Uint32 pos
285+
286+
cdef int line
287+
for line in range(sfc.h):
288+
pos = line * pitch;
289+
memcpy(&rpixels[pos], &pixels[(pxlength-pos)-pitch], pitch)
250290

291+
return result

kivy/core/window/window_sdl2.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ def set_icon(self, filename):
205205
self._win.set_window_icon(filename)
206206

207207
def screenshot(self, *largs, **kwargs):
208+
filename = super(WindowSDL, self).screenshot(*largs, **kwargs)
209+
if filename is None:
210+
return
211+
212+
from kivy.graphics.opengl import glReadPixels, GL_RGB, GL_UNSIGNED_BYTE
213+
width, height = self.size
214+
data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
215+
self._win.save_bytes_in_png(filename, data, width, height)
208216
return
209217
# TODO
210218
filename = super(WindowPygame, self).screenshot(*largs, **kwargs)

0 commit comments

Comments
 (0)