-
Notifications
You must be signed in to change notification settings - Fork 60
/
simplest.py
63 lines (53 loc) · 2.61 KB
/
simplest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/env python
# heatmap - High performance heatmap creation in C.
#
# The MIT License (MIT)
#
# Copyright (c) 2013 Lucas Beyer
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
from os.path import join as pjoin, dirname
from random import gauss
from ctypes import CDLL, POINTER, c_ulong, c_ubyte, c_void_p
w, h, npoints = 256, 512, 1000
# Load the heatmap library using ctypes
libhm = CDLL(pjoin(dirname(__file__), '..', 'libheatmap.so'))
# Here, we describe the signatures of the various functions.
# TBH, I'm not sure why this is necessary nowadays whereas it wasn't in the past.
# If someone knows, please explain in a Github issue, or a PR to here!
libhm.heatmap_new.argtypes = [c_ulong, c_ulong]
libhm.heatmap_new.restype = c_void_p
libhm.heatmap_add_point.argtypes = [c_void_p, c_ulong, c_ulong]
libhm.heatmap_render_default_to.argtypes = [c_void_p, POINTER(c_ubyte)]
libhm.heatmap_free.argtypes = [c_void_p]
# Create the heatmap object with the given dimensions (in pixel).
hm = libhm.heatmap_new(w, h)
# Add a bunch of random points to the heatmap now.
for x, y in ((int(gauss(w*0.5, w/6.0)), int(gauss(h*0.5, h/6.0))) for _ in range(npoints)):
libhm.heatmap_add_point(hm, c_ulong(x), c_ulong(y))
# This creates an image out of the heatmap.
# `rawimg` now contains the image data in 32-bit RGBA.
rawimg = (c_ubyte*(w*h*4))()
libhm.heatmap_render_default_to(hm, rawimg)
# Now that we've got a finished heatmap picture, we don't need the map anymore.
libhm.heatmap_free(hm)
# Use the PIL (for example) to make a png file out of that.
import Image
img = Image.frombuffer('RGBA', (w, h), rawimg, 'raw', 'RGBA', 0, 1)
img.save('heatmap.png')