kyamagu / skia-python Goto Github PK
View Code? Open in Web Editor NEWPython binding to Skia Graphics Library
Home Page: https://kyamagu.github.io/skia-python/
License: BSD 3-Clause "New" or "Revised" License
Python binding to Skia Graphics Library
Home Page: https://kyamagu.github.io/skia-python/
License: BSD 3-Clause "New" or "Revised" License
When I install via pip, I get the wheels published on PyPi. Example:
skia_python-87.1-cp39-cp39-macosx_10_14_x86_64.whl
However, they don't work :-( Erroring out on import with:
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/skia.cpython-39-darwin.so, 2): Symbol not found: _XML_ErrorString
Referenced from: /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/skia.cpython-39-darwin.so
Expected in: flat namespace
in /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/skia.cpython-39-darwin.so
Tested under the Python.org 3.9 installer, and conda-forge 3.8 and 3.9 -- same results on all three.
It seems that it's looking for the _XML_ErrorString symbol from expat, which is bundled with Python:
$ python -c "import xml.parsers.expat; print xml.parsers.expat.__version__"
$Revision: 17640 $
I'm totally guessing but I think it might be the "flat namespace" issue. The symbol is there in the extension:
$ grep "_XML_ErrorString" /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload/pyexpat.cpython-39-darwin.so
Binary file /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload/pyexpat.cpython-39-darwin.so matches
Sorry -- I've reached the end of what I know about these issues.
Is your feature request related to a problem? Please describe.
Current skia-python does not implement skottie
APIs
Describe the solution you'd like
Implement skottie APIs
Is your feature request related to a problem? Please describe.
Update the skia version to m86
Describe the solution you'd like
Fix API change
Describe alternatives you've considered
n/a
Additional context
Milestone 86 planned on Aug 20, 2020
Describe the bug
Example in docs raises exception
To Reproduce
Steps to reproduce the behavior:
pip install skia-python==86.0 glfw==1.12.0
AttributeError: type object 'skia.GrContext' has no attribute 'MakeGL'
Expected behavior
Working example in documentation
Desktop (please complete the following information):
I don't know if its package a sided issue, python sided or env sided. But every time I'm pip installing skia-python its given me this error:
ERROR: Could not find a version that satisfies the requirement skia-python==86.0 (from versions: none)
ERROR: No matching distribution found for skia-python==86.0
Is your feature request related to a problem? Please describe.
Skia's experimental APIs look useful. Implement some of them.
Describe the solution you'd like
Experimental APIs like SkSVGDOM
is wrapped in skia-python.
Describe alternatives you've considered
n/a
Additional context
See skia/experimental/
APIs.
Describe the bug
Traceback (most recent call last):
File "test.py", line 31, in <module>
surface = init_surface(width, height)
File "test.py", line 14, in init_surface
skia.GrGLFramebufferInfo(0, GL.GL_RGBA8))
AttributeError: module 'skia' has no attribute 'GrGLFramebufferInfo'
To Reproduce
Run
import skia
import glfw
from OpenGL import GL
width, height = 200, 200
def init_surface(width, height):
context = skia.GrContext.MakeGL()
backend_render_target = skia.GrBackendRenderTarget(
width,
height,
0, # sample count
0, # stencil bits
skia.GrGLFramebufferInfo(0, GL.GL_RGBA8))
surface = skia.Surface.MakeFromBackendRenderTarget(
context, backend_render_target, skia.kBottomLeft_GrSurfaceOrigin,
skia.kRGBA_8888_ColorType, skia.ColorSpace.MakeSRGB())
assert surface, 'Failed to create a surface'
return surface
if not glfw.init():
raise RuntimeError('glfw.init() failed')
glfw.window_hint(glfw.STENCIL_BITS, 0)
glfw.window_hint(glfw.DEPTH_BITS, 0)
window = glfw.create_window(640, 480, 'Demo', None, None)
glfw.make_context_current(window)
glfw.swap_interval(1)
surface = init_surface(width, height)
canvas = surface.getCanvas()
# Loop until the user closes the window
while not glfw.window_should_close(window):
glfw.wait_events()
# Render here
canvas.clear(skia.ColorGREEN)
surface.flushAndSubmit()
# Swap front and back buffers
glfw.swap_buffers(window)
# Poll for and process events
glfw.poll_events()
glfw.terminate()
Expected behavior
A clear and concise description of what you expected to happen.
Desktop (please complete the following information):
I'll preface this by saying Python Wheel naming schemes are bizarrely complex to my eye anyway so their may be a reason for this. However the new scheme includes even more duplicate or nonsense information that the last one:
skia_python-87.1-cp39-cp39-manylinux2014_x86_64.whl
skia_python-87.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Is the extra manylinux_2_17_86_64.
actually serving a purpose? It's bad enough that cp39
is duplicated...
As a distro packager every time something like this changes we have to go futz around and figure out what the new scheme is. It would be nice if it made more sense and didn't change between releases without good cause.
Is your feature request related to a problem? Please describe.
PDF metadata cannot be set because bindings to attr are not implemented
Describe the solution you'd like
Implement SkPDF::Metadata
bindings
Describe alternatives you've considered
n/a
Additional context
n/a
Describe the bug
Some iterators and enter-exit context manager does not implement keep alive policy to bindings.
https://pybind11.readthedocs.io/en/stable/advanced/functions.html?highlight=keep_alive#keep-alive
To Reproduce
See Path.Iter
implementation for example.
Expected behavior
There should be py::keep_alive<0, 1>()
policy.
Desktop (please complete the following information):
Additional context
n/a
Is your feature request related to a problem? Please describe.
Current skia-python does not have SkDocument APIs
Describe the solution you'd like
Implement wrappers
skia-python tutorial contains an example of rendering to a headless OpenGL context. I tried to modify the example to render to the actual window on the screen, but ended up with a black window:
import glfw
import skia
width, height = 640, 480
def main():
if not glfw.init():
return
glfw.window_hint(glfw.STENCIL_BITS, 8)
window = glfw.create_window(width, height, "Hello World", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
context = skia.GrContext.MakeGL()
info = skia.ImageInfo.MakeN32Premul(width, height)
surface = skia.Surface.MakeRenderTarget(context, skia.Budgeted.kNo, info)
assert surface is not None
while not glfw.window_should_close(window):
with surface as canvas:
canvas.drawCircle(100, 100, 40, skia.Paint(Color=skia.ColorGREEN))
surface.flushAndSubmit()
glfw.swap_buffers(window)
glfw.poll_events()
context.abandonContext()
glfw.terminate()
if __name__ == "__main__":
main()
I don't understand why it doesn't work. It would be nice to add to the documentation at least on example of rendering to a live window.
Is your feature request related to a problem? Please describe.
SkM44
bindings are not available now
Describe the solution you'd like
Implement them
Describe alternatives you've considered
n/a
Additional context
n/a
Is your feature request related to a problem? Please describe.
Current binding does not support ICC profile.
Describe the solution you'd like
Implement skcms API bindings.
Describe alternatives you've considered
n/a
Additional context
n/a
Describe the bug
The return value of typeface.getVariationDesignPosition()
contains a stray item, and does not give the expected result at all on Linux.
To Reproduce
I have created a tiny test project here: https://github.com/justvanrossum/skia-vf-bug
Expected behavior
I expected the test script to output this:
MutatorSans.ttf
{b'wdth': 0.0, b'wght': 0.0}
IBMPlexSansVar-Roman.ttf
{b'wght': 400.0, b'wdth': 100.0}
This should show the VF design position of the typeface (in this case the default).
However, on macOS and Windows the output is:
MutatorSans.ttf
{b'wdth': 0.0, b'wght': 0.0, b'\x00\x00\x00\x00': 0.0}
IBMPlexSansVar-Roman.ttf
{b'wght': 400.0, b'wdth': 100.0, b'\x00\x00\x00\x00': 0.0}
That is easy to work around. However, on Linux it outputs this:
MutatorSans.ttf
{b'\x00\x00\x00\x00': 0.0}
IBMPlexSansVar-Roman.ttf
{b'\x00\x00\x00\x00': 0.0}
Desktop:
Additional context
I alluded to this problem in #112, and in justvanrossum/drawbot-skia/issues/1
Describe the bug
skia.Path.ConvertConicToQuads()
does not appear to return the correct value.
To Reproduce
I translated this fiddle to Python:
https://fiddle.skia.org/c/@Path_ConvertConicToQuads
My Python version:
conictest.py.zip
The script fails with IndexError: list index out of range
Expected behavior
The returned quads
list contains only 2 points, but according to the fiddle it should contain 5.
Desktop (please complete the following information):
pil_image = Image.open('images/375edc92b74a7c334f08ee765e6522eae8531971.png')
image = skia.Image.frombytes(pil_image.tobytes(), pil_image.size, skia.kRGBA_8888_ColorType)
Does skia-python support sksl (Skia’s shading language)?
Is your feature request related to a problem? Please describe.
Skia milestone 88 is released https://skia.org/user/release/release_notes
Describe the solution you'd like
Upgrade dependent skia to m88
Describe alternatives you've considered
n/a
Additional context
n/a
Describe the bug
There are docstrings that has arg0
, arg1
stub argument signature, such as FontStyle
.
To Reproduce
Check the documentation page
Expected behavior
Stub argument should get proper names.
Desktop (please complete the following information):
Additional context
n/a
I'm using Python 3.7.6 on win32 (windows 10 x64).
Could you build a package which can run on win32?
Is your feature request related to a problem? Please describe.
Smart pointer methods: unique
, ref
, unref
are all inherited from SkRefCnt or SkNVRefCnt. They have duplicate bindings in subclasses.
Describe the solution you'd like
Implement RefCntBase as Python trampoline class and reduce code duplicates.
Describe alternatives you've considered
n/a
Additional context
n/a
Describe the bug
The optional index
argument of skia.Typeface.MakeFromFile(path, index=0)
is supposed to be the index to a font in a .ttc (TT collection) file, but this does not work.
To Reproduce
Steps to reproduce the behavior:
>>> import skia
>>> p = "/Users/just/code/git/fontgoggles/Tests/data/MutatorSans/MutatorSans.ttc"
>>> skia.Typeface.MakeFromFile(p, 0)
Typeface('MutatorMathTest', FontStyle(400, 5, Slant.kUpright_Slant))
>>> skia.Typeface.MakeFromFile(p, 1)
>>>
Expected behavior
The second call to skia.Typeface.MakeFromFile()
should also return a Typeface, but it returns None.
Desktop (please complete the following information):
Additional context
Here is a .ttc file to test with (but any .ttc should show the problem)
MutatorSans.ttc.zip
Describe the bug
Method bindings are missing Canvas.drawDrawable
, Canvas.drawImageLattice
.
To Reproduce
canvas.drawDrawable
throws an error.
Expected behavior
Bindings and tests should be properly implemented
Desktop (please complete the following information):
Additional context
n/a
Describe the bug
APIs that return memoryview
does not have valid format, forcing the user to call cast('B')
before using any memory manipulation.
To Reproduce
view = pixmap.addr8()
view[0] # This crash
view.cast('B')[0]
Expected behavior
Should not require cast
Desktop (please complete the following information):
Additional context
See pybind/pybind11#2223
Describe the bug
Linux binary wheel fails to upload to PyPI due to 60MB default file size limit
To Reproduce
twine upload dist/*.whl
Expected behavior
Upload should succeed
Desktop (please complete the following information):
Additional context
pypa/packaging-problems#86
I have been trying to output the skia drawing on glfw window. This is the code I have (not working):
import skia
import glfw
import contextlib
import time
width, height = 200, 200
if not glfw.init():
raise RuntimeError('glfw.init() failed')
#glfw.window_hint(glfw.VISIBLE, glfw.FALSE)
glfw.window_hint(glfw.STENCIL_BITS, 8)
window = glfw.create_window(640, 480, 'Processing', None, None)
glfw.make_context_current(window)
context = skia.GrContext.MakeGL()
info = skia.ImageInfo.MakeN32Premul(width, height)
surface = skia.Surface.MakeRenderTarget(context, skia.Budgeted.kNo, info)
canvas = surface.getCanvas()
canvas.drawCircle(100, 100, 40, skia.Paint(Color=skia.ColorGREEN))
# Loop until the user closes the window
while not glfw.window_should_close(window):
# Render here, e.g. using pyOpenGL
# Swap front and back buffers
glfw.swap_buffers(window)
# Poll for and process events
glfw.poll_events()
glfw.terminate()
Is there anything that can be done to make this work?
Is your feature request related to a problem? Please describe.
I'm attempting to write a basic and GUI "toolkit" using skia-python
as I find it hard Qt and GTK programming and liked too much Skia's general flexibility, but for making "widgets" like a file explorer or a combo box or input text it's no good to show everything at once (the items on a list), we need to limit the render "target region".
Describe the solution you'd like
I tried finding documentation on it and couldn't, sorry if it's there and exists, I wanted to do something like:
canvas.draw(what, x, y, paint, REGION)
This regions limits on where Skia will stop writing to the canvas window, let's saw I write a text of size (w=200, h=20)
at coordinate (x=0, y=0)
and specify a region of:
REGION = (Xstart=0, Ystart=0, Xend=100, Yend=20)
So in this case it'll only render half the text, more specifically the first half of it and won't render the outside parts of this rectangle.
Describe alternatives you've considered
I could draw into a new canvas and then merge the two but that'd make things spaghetti and I'm not sure how OpenGL would behave, I considered hard drawing the outside of the region with black rectangles but that will overwrite the other parts of the GUI.
Additional context
Thanks for this binding / package, it saved me a lot of SVG pain I had and is really fast under Python.
Currently tests on Windows crash when calling certain APIs (e.g., Surface). Investigate what causes crash.
Describe the bug
I am unable to install skia-python using pip on macOS Big Sur 11.0.1, error: "Could not find a version that satisfies the requirement skia-python".
To Reproduce
Setting up a new project using venv, updating pip, then installing skia-python:
/tmp ➤ python3 -m venv skia-bigsur
/tmp ➤ cd skia-bigsur
skia-bigsur ➤ source bin/activate
(skia-bigsur) skia-bigsur ➤ python -m pip install --upgrade pip
...
(skia-bigsur) skia-bigsur ➤ python -m pip install skia-python
ERROR: Could not find a version that satisfies the requirement skia-python (from versions: none)
ERROR: No matching distribution found for skia-python
However, when I download and rename the wheel file from pypi, it seems to be able to install it just fine and lets me import:
(skia-bigsur) skia-bigsur ➤ wget https://files.pythonhosted.org/packages/a1/17/4973bc6ae96e418f4ff8c1cc664d95d33714017bd70e7dee460587b18ab6/skia_python-87.0-cp39-cp39-macosx_10_14_x86_64.whl
(skia-bigsur) skia-bigsur ➤ mv skia_python-87.0-cp39-cp39-macosx_10_14_x86_64.whl skia_python-87.0-cp39-cp39-macosx_11_0_x86_64.whl
(skia-bigsur) skia-bigsur ➤ python -m pip install skia_python-87.0-cp39-cp39-macosx_11_0_x86_64.whl
...
(skia-bigsur) skia-bigsur ➤ python
Python 3.9.0 (default, Nov 21 2020, 14:55:42)
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import skia
>>>
Expected behavior
skia-python should install successfully
Desktop (please complete the following information):
Is your feature request related to a problem? Please describe.
I would like to use skia with glfw (to display realtime graphics, similar to here).
The issue is that the current bindings don't expose the correct GrBackendRenderTarget constructors since they are under an #if SK_SUPPORT_GPU
, as it can be seen in the .h file.
Describe the solution you'd like
I guess you are generating the bindings in some automated way, so it should be as simple as setting SK_SUPPORT_GPU to true when generating them.
Describe alternatives you've considered
I wasn't able to use the GPU example you provided in the docs to to that, it can only generate an image.
Describe the bug
ColorSpace
is not tested at all.
To Reproduce
pytest
Expected behavior
All methods should be unit-tested.
Desktop (please complete the following information):
Additional context
n/a
https://docs.microsoft.com/en-us/dotnet/api/skiasharp.skpaint.textalign?view=skiasharp-1.68.2
There are no bindings to the paint.textAlign
property in Paint
class, can you add it?
Describe the bug
Building on throws an error that get_pybind_include is not iterable
TypeError: argument of type 'get_pybind_include' is not iterable
To Reproduce
Steps to reproduce the behavior:
python setup.py install
Expected behavior
Normal build
Desktop (please complete the following information):
Additional context
I managed to bypass this by adding
def __iter__(self): import pybind11 yield pybind11.get_include(self.user)
Not sure if this is an environment problem thats my own but seems really strange.
Describe the bug
When iterating over a skia.Path(), the iterator.conicWeight()
call does not return the expected result.
To Reproduce
Run this script:
import skia
def draw(canvas):
verbNames = ["move", "line", "quad", "conic", "cubic", "close", "done"]
path = skia.Path()
path.addOval((0, 0, 100, 100))
iterator = iter(path)
path2 = skia.Path()
for verb, points in iterator:
print(verbNames[verb], end=" ")
for point in points:
print(f"{{{point.x()}, {point.y()}}}, ", end="")
if verb == skia.Path.Verb.kConic_Verb:
print(f"weight = {iterator.conicWeight()}", end="")
print()
draw(None)
The output will be something like this:
move {100.0, 50.0},
conic {100.0, 50.0}, {100.0, 100.0}, {50.0, 100.0}, weight = 4.13163043116922e-40
conic {50.0, 100.0}, {0.0, 100.0}, {0.0, 50.0}, weight = 4.13163043116922e-40
conic {0.0, 50.0}, {0.0, 0.0}, {50.0, 0.0}, weight = 4.13163043116922e-40
conic {50.0, 0.0}, {100.0, 0.0}, {100.0, 50.0}, weight = 4.13163043116922e-40
close {100.0, 50.0},
Expected behavior
Here is a Skia fiddle with an equivalent program:
https://fiddle.skia.org/c/074e45912d56806f380222d7e5bda985
The output there is:
move {100, 50},
conic {100, 50}, {100, 100}, {50, 100}, weight = 0.707107
conic {50, 100}, {0, 100}, {0, 50}, weight = 0.707107
conic {0, 50}, {0, 0}, {50, 0}, weight = 0.707107
conic {50, 0}, {100, 0}, {100, 50}, weight = 0.707107
close {100, 50},
done
Desktop (please complete the following information):
Additional context
The results actually vary, hinting that perhaps some uninitialized memory is involved.
Describe the bug
Windows CI build fails
To Reproduce
Launch build in Github Actions windows runner
Expected behavior
Build should succeed.
Desktop (please complete the following information):
Additional context
See https://skia.googlesource.com/skia/+/0d6f81593b1fa222e8e4afb56cc961ce8c9be375
https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes#16.7.0
https://github.com/microsoft/STL/wiki/Changelog#vs-2019-167
Is your feature request related to a problem? Please describe.
Re-organize binding codes according to Skia header structure. Also rename stub class name in a consistent manner; e.g., from:
py::class_<SkColorFilter, sk_sp<SkColorFilter>, SkFlattenable> colorfilter(m, "ColorFilter");
to:
py::class_<SkColorFilter, sk_sp<SkColorFilter>, SkFlattenable> ColorFilter(m, "ColorFilter");
This is to improve code maintenance over skia version upgrades.
Describe the solution you'd like
In Skia, header files are organized under different directories by categories, such as include/core/*.h
or include/gpu/*.h
. Presumably, the python package should be also split according to this structure.
Describe alternatives you've considered
n/a
Additional context
n/a
Is your feature request related to a problem? Please describe.
Intellisense/autocomplete doesn't work in Visual Studio Code when using Pylance as the language server.
It works when using Jedi or the Microsoft language server but it still has issues understanding the return types of functions.
Describe the solution you'd like
This is a known "issue" with Pylance, but they say it is a design choice. The solution should be to generate type stubs as discussed in this issue.
There is a discussion on how to automatically generate stubs for pybind11 here and the options seems to be either pybind11-stubgen or mypy's stubgen.
Describe alternatives you've considered
I could use a different LS such as Jedi but it's worse in general and there would still be issues.
Additional context
Describe the bug
NumPy array conversion to, e.g., Image
silently accepts array with types other than uint8.
To Reproduce
import skia
import numpy as np
array = np.zeros((100, 100), dtype=np.float32)
image = skia.Image(array)
Expected behavior
Should throw an error.
Desktop (please complete the following information):
Additional context
n/a
Is your feature request related to a problem? Please describe.
pybind11 v2.6 is almost ready. upgrade the dependency to resolve #62
Describe the solution you'd like
https://pybind11.readthedocs.io/en/latest/upgrade.html#upgrade-guide-2-6
Describe alternatives you've considered
n/a
Additional context
n/a
Is your feature request related to a problem? Please describe.
PIL.Image.fromarray
uses __array_interface__
to convert from array. Support this dict for easier conversion between PIL Image.
Describe the solution you'd like
Implement array interface.
Describe alternatives you've considered
Currently frombytes
is the only approach to directly load pixels.
Additional context
https://numpy.org/devdocs/reference/arrays.interface.html
Is your feature request related to a problem? Please describe.
Currently pixel buffers are exposed via memoryview
. Add __getitem__
and __setitem__
for pixel access.
Describe the solution you'd like
Implement __getitem__
and __setitem__
.
Describe alternatives you've considered
NumPy array bind is alternative, but requires numpy import.
Additional context
n/a
Is your feature request related to a problem? Please describe.
I'm a beginner at Python and have been looking as Skia recently and wanted to use some of it's unique features. This is the first(only?) python library that seems to be complete that i found. Could you please add some examples of interaction or exchange of information with Pillow and Wand. And also saving or reading from files. ie eliminate use of ipython calls.
Describe the solution you'd like
Examples
Describe alternatives you've considered
Could not get the Ipython package working on my system so was a bit lost of how to use skia-python. it does appear to work but can't show or display or save to file.
Describe the bug
The paths returned by font.getPaths(gids)
are wrongly scaled.
To Reproduce
Steps to reproduce the behavior:
Run this script:
import skia
font = skia.Font(skia.Typeface(None), 100)
gid = 15
path1 = font.getPath(gid)
print(path1.getBounds())
paths = font.getPaths([gid])
print(paths[0].getBounds())
Compare the first line of the output (which is correct) with the second line (which should be the same):
Rect(8.30078, -10.6445, 18.75, 14.8438)
Rect(5.3125, -6.8125, 12, 9.5)
If I change the font size, the first line changes as expected, but the second stays the same.
(This is with the default font on macOS, so the actual numbers may vary per platform.)
Expected behavior
font.getPath(gid)
does work as expected (so that's the workaround as well, making this issue super low priority).
Desktop (please complete the following information):
The SkTypeface::getVariationDesignParameters
method doesn't seem to be exposed to Python.
It's companion SkTypeface::getVariationDesignPosition
is there.
(Btw. skia-python is fantastic! I'm having a lot of fun with it.)
Describe the bug
After upgrading skia milestone to 84, GrContext.createBackendTexture()
crashes for the signatures taking SurfaceCharacterization
object.
To Reproduce
Call GrContext.createBackendTexture()
with SurfaceCharacterization
.
Expected behavior
Should not crash.
Desktop (please complete the following information):
Additional context
N/A
Is your feature request related to a problem? Please describe.
Skia milestone 87 is out
Describe the solution you'd like
skia-python should upgrade skia
Describe alternatives you've considered
n/a
Additional context
https://skia.org/user/release/release_notes
Describe the bug
Windows build of the package is broken in recent versions of Python due to bpo-38597
To Reproduce
Build the package in Windows VM on Python >= 3.7
Expected behavior
Should build and run without an error
Desktop (please complete the following information):
Additional context
See also https://github.com/python/cpython/blob/master/Lib/distutils/_msvccompiler.py
I would like to use path operations like "difference", "union", "intersection", etc. with the skia.PathOp
enum values.
I think I need the Op
function, as declared in https://github.com/google/skia/blob/master/include/pathops/SkPathOps.h:
I can't find this in skia-python, so I assume this is not yet implemented.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.