Kivy-examples 2.3.1.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/main.py +77 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/monkey.obj +7966 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/objloader.py +147 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/3Drendering/simple.glsl +47 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/RST_Editor/editor.kv +72 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/RST_Editor/main.py +64 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/compass.kv +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/main.py +77 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/needle.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/compass/rose.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/main.py +80 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/shadow32.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/android/takepicture/takepicture.kv +40 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/animation/animate.py +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_suite.py +152 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_suite_data/testkvdir.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_build.py +24 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_config.py +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_kv.py +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/app_with_kv_in_template1.py +27 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/template1/test.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/test.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/application/testkvfile.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/asyncio_advanced.py +90 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/asyncio_basic.py +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/trio_advanced.py +93 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/async/trio_basic.py +58 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12908_sweet_trip_mm_clap_hi.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12909_sweet_trip_mm_clap_lo.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12910_sweet_trip_mm_clap_mid.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12911_sweet_trip_mm_hat_cl.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12913_sweet_trip_mm_kick_hi.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12914_sweet_trip_mm_kick_lo.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12915_sweet_trip_mm_kick_mid.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12916_sweet_trip_mm_kwik_mod_01.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12917_sweet_trip_mm_kwik_mod_02.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12918_sweet_trip_mm_kwik_mod_03.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12919_sweet_trip_mm_kwik_mod_04.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12920_sweet_trip_mm_kwik_mod_05.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12921_sweet_trip_mm_kwik_mod_06.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12922_sweet_trip_mm_kwik_mod_07.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12923_sweet_trip_mm_metal_clave.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12925_sweet_trip_mm_sweep_x.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12926_sweet_trip_mm_sweep_y.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/12927_sweet_trip_mm_sweep_z.wav +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/audio.kv +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/main.py +81 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/audio/pitch.py +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/camera/main.py +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/bezier.py +105 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/canvas_stress.py +72 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/circle.py +84 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/fbo_canvas.py +91 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/kiwi.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/lines.py +296 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/lines_extended.py +183 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mesh.py +57 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mesh_manipulation.py +101 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mtexture1.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/mtexture2.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/multitexture.py +110 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/repeat_texture.py +65 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/rotation.py +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/rounded_rectangle.py +153 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/scale.py +37 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/stencil_canvas.py +85 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/tesselate.py +146 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/texture.py +143 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/canvas/texture_example_image.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/1.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/2.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/3.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/kv/root.kv +32 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/container/main.py +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/cover/cover_image.py +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/cover/cover_video.py +31 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/camera_puzzle.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/AnchorLayoutContainer.kv +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/BoxLayoutContainer.kv +14 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/ButtonContainer.kv +27 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/CheckBoxContainer.kv +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/FileChooserContainer.kv +19 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/FloatLayoutContainer.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/GridLayoutContainer.kv +20 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/LabelContainer.kv +62 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/MediaContainer.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/PlaygroundContainer.kv +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/PopupContainer.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/ProgressBarContainer.kv +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/RestContainer.kv +5 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/ScatterContainer.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/SelectorsContainer.kv +10 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/StackLayoutContainer.kv +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/container_kvs/TextContainer.kv +20 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/kivycatalog.kv +144 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/kivycatalog/main.py +192 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/gesturedatabase.kv +117 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/gesturedatabase.py +180 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/helpers.py +30 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/historymanager.kv +164 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/historymanager.py +276 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/main.py +144 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/multistroke.kv +101 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/settings.kv +110 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/multistroke/settings.py +97 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/Bubbles.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/Ill1.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/Wall.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/images/faust_github.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/main.py +73 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/pictures.kv +57 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/pictures/shadow32.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/shadereditor/main.py +147 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/shadereditor/shadereditor.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/README.txt +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/background.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/faust_github.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/README +4 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/bug.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/chevron-left.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/icons/chevron-right.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/accordions.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/bubbles.kv +33 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/buttons.kv +26 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/carousel.kv +51 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/checkboxes.kv +33 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/codeinput.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/dropdown.kv +40 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/filechoosers.kv +24 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/popups.kv +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/progressbar.kv +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/rstdocument.kv +24 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/scatter.kv +14 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/screenmanager.kv +46 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/sliders.kv +55 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/spinner.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/splitter.kv +13 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/switches.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/tabbedpanel + layouts.kv +69 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/textinputs.kv +48 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/data/screens/togglebutton.kv +39 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/main.py +243 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/showcase/showcase.kv +100 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/README.txt +12 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/icon.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/main.py +170 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/particle.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/demo/touchtracer/touchtracer.kv +29 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/frameworks/twisted/echo_client_app.py +82 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/frameworks/twisted/echo_server_app.py +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/frameworks/twisted/twistd_app.py +66 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/gestures/gesture_board.py +95 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/gestures/my_gestures.py +90 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/designwithkv/controller.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/designwithkv/main.py +29 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/1_skeleton.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/2_print_touch.py +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/3_draw_ellipse.py +22 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/4_draw_line.py +26 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/5_random_colors.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/firstwidget/6_button.py +38 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/guide/quickstart/main.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/button.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/layout.kv +6 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/main.py +19 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/includes/test.kv +5 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/keyboard/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/keyboard/main.py +226 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/keyboard/numeric.json +38 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kinect/README.txt +13 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kinect/kinectviewer.py +283 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_button.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_camera.kv +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_fbo.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_layout.kv +23 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_logo.kv +36 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_scatter.kv +6 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_stencil.kv +27 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/app_video.kv +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/builder_template.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/id_in_kv/id_in_kv.py +20 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/id_in_kv/test.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/kv_and_py/kv_and_py.py +34 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/ids/kv_and_py/test.kv +11 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/kivy.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/kv/kvrun.py +38 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/clipboard.py +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/custom_titlebar.py +56 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/imagesave.py +14 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/joystick.py +83 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/multiple_dropfile.py +51 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/on_textedit_event.py +104 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/opacitywindow.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/shapecollisions.py +397 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/shapedwindow.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/two_panes.py +47 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/miscellaneous/urlrequest.py +128 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/settings/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/settings/main.py +122 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/plasma.kv +9 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/plasma.py +86 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/rotated.kv +91 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/rotated.py +102 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/shadertree.kv +29 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/shadertree.py +193 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/shader/tex3.jpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/benchmark.py +19 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/cloud.svg +25 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/main-smaa.py +155 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/main.py +50 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/music.svg +68 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/rotated.svg +23 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/ship.svg +181 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/sun.svg +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/svg/tiger.svg +813 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/text/pango_demo.py +296 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/notes/final/data/icon.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/notes/final/main.py +163 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/notes/final/note.kv +154 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/main.py +82 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/pong.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step1/main.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step1/pong.kv +2 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step2/main.py +15 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step2/pong.kv +21 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step3/main.py +26 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step3/pong.kv +31 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step4/main.py +48 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step4/pong.kv +34 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step5/main.py +75 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/tutorials/pong/steps/step5/pong.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/accordion_1.py +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/actionbar.py +32 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/asyncimage.py +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/boxlayout_poshint.py +54 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/bubble_test.py +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/camera.py +33 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/carousel_buttons.py +50 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/cityCC0.mpg +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/cityCC0.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/codeinput.py +225 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/codeinputtest.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/colorpicker.py +234 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/colorusage.py +62 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/compound_selection.py +83 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/customcollide.py +82 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/effectwidget.py +193 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/effectwidget2.py +47 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/effectwidget3_advanced.py +62 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/fbowidget.py +111 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/focus_behavior.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/image_mipmap.py +31 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/keyboardlistener.py +42 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_mipmap.py +28 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_sizing.py +193 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_text_size.py +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/label_with_markup.py +21 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/lang_dynamic_classes.py +18 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/pagelayout.py +64 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/popup_with_kv.py +35 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/basic_data.py +124 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/infinite_scrolling.py +143 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/key_viewclass.py +149 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/messenger.py +196 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/pull_to_refresh.py +95 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/recycleview/rv_animate_items.py +109 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/rstexample.py +128 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scatter.kv +53 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scatter.py +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/screenmanager.py +106 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scrollview.kv +16 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/scrollview.py +40 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/android.txt +3 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/bird.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/button_white.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/button_white_animated.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/cube.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/info.png +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/info.zip +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/data/images/simple_cv_joint_animated.gif +0 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/main.kv +63 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/main.py +150 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/uix/__init__.py +7 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/sequenced_images/uix/custom_button.py +98 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/settings.py +93 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/shorten_text.py +80 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/spinner.py +17 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/splitter.py +74 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/tabbed_panel_showcase.py +316 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/tabbedpanel.py +50 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/textalign.kv +49 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/textalign.py +48 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/textinput.py +59 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/unicode_textinput.py +244 -0
- Kivy_examples-2.3.1.dev0.data/data/share/kivy-examples/widgets/videoplayer.py +26 -0
- Kivy_examples-2.3.1.dev0.dist-info/AUTHORS +66 -0
- Kivy_examples-2.3.1.dev0.dist-info/LICENSE +21 -0
- Kivy_examples-2.3.1.dev0.dist-info/METADATA +382 -0
- Kivy_examples-2.3.1.dev0.dist-info/RECORD +624 -0
- Kivy_examples-2.3.1.dev0.dist-info/WHEEL +5 -0
- Kivy_examples-2.3.1.dev0.dist-info/dependency_links.txt +1 -0
- Kivy_examples-2.3.1.dev0.dist-info/top_level.txt +1 -0
- kivy/__init__.py +519 -0
- kivy/_version.py +18 -0
- kivy/animation.py +831 -0
- kivy/app.py +1213 -0
- kivy/atlas.py +456 -0
- kivy/base.py +617 -0
- kivy/cache.py +262 -0
- kivy/clock.py +1172 -0
- kivy/compat.py +82 -0
- kivy/config.py +1004 -0
- kivy/context.py +102 -0
- kivy/core/__init__.py +247 -0
- kivy/core/audio/__init__.py +223 -0
- kivy/core/audio/audio_android.py +104 -0
- kivy/core/audio/audio_avplayer.py +82 -0
- kivy/core/audio/audio_ffpyplayer.py +185 -0
- kivy/core/audio/audio_gstplayer.py +101 -0
- kivy/core/audio/audio_pygame.py +127 -0
- kivy/core/camera/__init__.py +151 -0
- kivy/core/camera/camera_android.py +206 -0
- kivy/core/camera/camera_gi.py +170 -0
- kivy/core/camera/camera_opencv.py +163 -0
- kivy/core/camera/camera_picamera.py +96 -0
- kivy/core/clipboard/__init__.py +157 -0
- kivy/core/clipboard/_clipboard_ext.py +36 -0
- kivy/core/clipboard/clipboard_android.py +91 -0
- kivy/core/clipboard/clipboard_dbusklipper.py +41 -0
- kivy/core/clipboard/clipboard_dummy.py +26 -0
- kivy/core/clipboard/clipboard_gtk3.py +47 -0
- kivy/core/clipboard/clipboard_nspaste.py +44 -0
- kivy/core/clipboard/clipboard_pygame.py +67 -0
- kivy/core/clipboard/clipboard_sdl2.py +36 -0
- kivy/core/clipboard/clipboard_winctypes.py +107 -0
- kivy/core/clipboard/clipboard_xclip.py +29 -0
- kivy/core/clipboard/clipboard_xsel.py +26 -0
- kivy/core/gl/__init__.py +90 -0
- kivy/core/image/__init__.py +996 -0
- kivy/core/image/img_dds.py +40 -0
- kivy/core/image/img_ffpyplayer.py +87 -0
- kivy/core/image/img_pil.py +123 -0
- kivy/core/image/img_pygame.py +119 -0
- kivy/core/image/img_sdl2.py +66 -0
- kivy/core/image/img_tex.py +58 -0
- kivy/core/spelling/__init__.py +135 -0
- kivy/core/spelling/spelling_enchant.py +50 -0
- kivy/core/spelling/spelling_osxappkit.py +64 -0
- kivy/core/text/__init__.py +1090 -0
- kivy/core/text/markup.py +893 -0
- kivy/core/text/text_pango.py +145 -0
- kivy/core/text/text_pil.py +84 -0
- kivy/core/text/text_pygame.py +117 -0
- kivy/core/text/text_sdl2.py +50 -0
- kivy/core/video/__init__.py +219 -0
- kivy/core/video/video_ffmpeg.py +106 -0
- kivy/core/video/video_ffpyplayer.py +449 -0
- kivy/core/video/video_gstplayer.py +140 -0
- kivy/core/video/video_null.py +12 -0
- kivy/core/window/__init__.py +2515 -0
- kivy/core/window/window_egl_rpi.py +86 -0
- kivy/core/window/window_pygame.py +441 -0
- kivy/core/window/window_sdl2.py +999 -0
- kivy/deps/__init__.py +6 -0
- kivy/effects/__init__.py +23 -0
- kivy/effects/dampedscroll.py +114 -0
- kivy/effects/kinetic.py +193 -0
- kivy/effects/opacityscroll.py +27 -0
- kivy/effects/scroll.py +126 -0
- kivy/event.py +12 -0
- kivy/eventmanager/__init__.py +185 -0
- kivy/extras/__init__.py +0 -0
- kivy/extras/highlight.py +52 -0
- kivy/factory.py +190 -0
- kivy/factory_registers.py +201 -0
- kivy/garden/__init__.py +186 -0
- kivy/geometry.py +121 -0
- kivy/gesture.py +424 -0
- kivy/graphics/__init__.py +126 -0
- kivy/graphics/cgl_backend/__init__.py +0 -0
- kivy/input/__init__.py +39 -0
- kivy/input/factory.py +35 -0
- kivy/input/motionevent.py +587 -0
- kivy/input/postproc/__init__.py +27 -0
- kivy/input/postproc/calibration.py +200 -0
- kivy/input/postproc/dejitter.py +74 -0
- kivy/input/postproc/doubletap.py +101 -0
- kivy/input/postproc/ignorelist.py +47 -0
- kivy/input/postproc/retaintouch.py +93 -0
- kivy/input/postproc/tripletap.py +106 -0
- kivy/input/provider.py +40 -0
- kivy/input/providers/__init__.py +68 -0
- kivy/input/providers/androidjoystick.py +117 -0
- kivy/input/providers/hidinput.py +778 -0
- kivy/input/providers/leapfinger.py +113 -0
- kivy/input/providers/linuxwacom.py +396 -0
- kivy/input/providers/mactouch.py +220 -0
- kivy/input/providers/mouse.py +424 -0
- kivy/input/providers/mtdev.py +380 -0
- kivy/input/providers/probesysfs.py +254 -0
- kivy/input/providers/tuio.py +326 -0
- kivy/input/providers/wm_common.py +162 -0
- kivy/input/providers/wm_pen.py +121 -0
- kivy/input/providers/wm_touch.py +157 -0
- kivy/input/recorder.py +335 -0
- kivy/input/shape.py +27 -0
- kivy/interactive.py +335 -0
- kivy/lang/__init__.py +883 -0
- kivy/lang/builder.py +1004 -0
- kivy/lang/parser.py +822 -0
- kivy/lib/__init__.py +21 -0
- kivy/lib/ddsfile.py +419 -0
- kivy/lib/gstplayer/__init__.py +27 -0
- kivy/lib/mtdev.py +254 -0
- kivy/lib/vidcore_lite/__init__.py +0 -0
- kivy/loader.py +579 -0
- kivy/logger.py +646 -0
- kivy/metrics.py +421 -0
- kivy/modules/__init__.py +300 -0
- kivy/modules/_webdebugger.py +200 -0
- kivy/modules/console.py +1059 -0
- kivy/modules/cursor.py +75 -0
- kivy/modules/inspector.py +755 -0
- kivy/modules/joycursor.py +299 -0
- kivy/modules/keybinding.py +64 -0
- kivy/modules/monitor.py +90 -0
- kivy/modules/recorder.py +94 -0
- kivy/modules/screen.py +183 -0
- kivy/modules/showborder.py +33 -0
- kivy/modules/touchring.py +97 -0
- kivy/modules/webdebugger.py +30 -0
- kivy/multistroke.py +1477 -0
- kivy/network/__init__.py +7 -0
- kivy/network/urlrequest.py +794 -0
- kivy/parser.py +154 -0
- kivy/resources.py +102 -0
- kivy/storage/__init__.py +405 -0
- kivy/storage/dictstore.py +98 -0
- kivy/storage/jsonstore.py +92 -0
- kivy/storage/redisstore.py +103 -0
- kivy/support.py +267 -0
- kivy/tests/__init__.py +11 -0
- kivy/tests/async_common.py +568 -0
- kivy/tests/common.py +524 -0
- kivy/tests/conftest.py +33 -0
- kivy/tests/fixtures.py +169 -0
- kivy/tests/perf_test_textinput.py +195 -0
- kivy/tests/pyinstaller/simple_widget/main.py +12 -0
- kivy/tests/pyinstaller/simple_widget/project/__init__.py +0 -0
- kivy/tests/pyinstaller/simple_widget/project/widget.py +12 -0
- kivy/tests/pyinstaller/test_pyinstaller.py +115 -0
- kivy/tests/pyinstaller/video_widget/main.py +6 -0
- kivy/tests/pyinstaller/video_widget/project/__init__.py +38 -0
- kivy/tests/test_animations.py +415 -0
- kivy/tests/test_app.py +216 -0
- kivy/tests/test_audio.py +69 -0
- kivy/tests/test_benchmark.py +292 -0
- kivy/tests/test_clipboard.py +48 -0
- kivy/tests/test_clock.py +292 -0
- kivy/tests/test_compat.py +6 -0
- kivy/tests/test_config.py +35 -0
- kivy/tests/test_coverage.py +83 -0
- kivy/tests/test_doc_gallery.py +38 -0
- kivy/tests/test_environ_cli.py +50 -0
- kivy/tests/test_fbo_py2py3.py +74 -0
- kivy/tests/test_filechooser.py +11 -0
- kivy/tests/test_filechooser_unicode.py +82 -0
- kivy/tests/test_fonts.py +42 -0
- kivy/tests/test_garden.py +23 -0
- kivy/tests/test_graphics.py +1149 -0
- kivy/tests/test_graphics_svg.py +84 -0
- kivy/tests/test_image.py +74 -0
- kivy/tests/test_imageloader.py +485 -0
- kivy/tests/test_invalid_lang.py +42 -0
- kivy/tests/test_issues/test_6315.py +55 -0
- kivy/tests/test_issues/test_issue_1084.py +47 -0
- kivy/tests/test_issues/test_issue_1091.py +19 -0
- kivy/tests/test_issues/test_issue_599.py +21 -0
- kivy/tests/test_issues/test_issue_609.py +19 -0
- kivy/tests/test_issues/test_issue_6909.py +28 -0
- kivy/tests/test_issues/test_issue_883.py +12 -0
- kivy/tests/test_kivy_init.py +30 -0
- kivy/tests/test_knspace.py +247 -0
- kivy/tests/test_lang.py +431 -0
- kivy/tests/test_lang_complex.py +87 -0
- kivy/tests/test_lang_pre_process_and_post_process.py +394 -0
- kivy/tests/test_logger.py +516 -0
- kivy/tests/test_metrics.py +30 -0
- kivy/tests/test_module_inspector.py +382 -0
- kivy/tests/test_motion_event.py +44 -0
- kivy/tests/test_mouse_hover_event.py +249 -0
- kivy/tests/test_mouse_multitouchsim.py +554 -0
- kivy/tests/test_multistroke.py +389 -0
- kivy/tests/test_properties.py +1332 -0
- kivy/tests/test_resources.py +79 -0
- kivy/tests/test_rst_replace.py +63 -0
- kivy/tests/test_screen.py +38 -0
- kivy/tests/test_storage.py +135 -0
- kivy/tests/test_uix_actionbar.py +363 -0
- kivy/tests/test_uix_anchorlayout.py +79 -0
- kivy/tests/test_uix_asyncimage.py +133 -0
- kivy/tests/test_uix_boxlayout.py +94 -0
- kivy/tests/test_uix_bubble.py +425 -0
- kivy/tests/test_uix_carousel.py +93 -0
- kivy/tests/test_uix_colorpicker.py +77 -0
- kivy/tests/test_uix_dropdown.py +91 -0
- kivy/tests/test_uix_gridlayout.py +244 -0
- kivy/tests/test_uix_layout.py +16 -0
- kivy/tests/test_uix_modal.py +101 -0
- kivy/tests/test_uix_recyclegridlayout.py +383 -0
- kivy/tests/test_uix_relativelayout.py +30 -0
- kivy/tests/test_uix_scrollview.py +358 -0
- kivy/tests/test_uix_settings.py +33 -0
- kivy/tests/test_uix_slider.py +156 -0
- kivy/tests/test_uix_stacklayout.py +120 -0
- kivy/tests/test_uix_textinput.py +577 -0
- kivy/tests/test_uix_translate_coordinates.py +72 -0
- kivy/tests/test_uix_videoplayer.py +112 -0
- kivy/tests/test_uix_widget.py +137 -0
- kivy/tests/test_urlrequest/test_urlrequest_requests.py +378 -0
- kivy/tests/test_urlrequest/test_urlrequest_urllib.py +155 -0
- kivy/tests/test_utils.py +237 -0
- kivy/tests/test_vector.py +256 -0
- kivy/tests/test_video.py +25 -0
- kivy/tests/test_weakmethod.py +44 -0
- kivy/tests/test_widget.py +127 -0
- kivy/tests/test_widget_walk.py +70 -0
- kivy/tests/test_window_base.py +60 -0
- kivy/tests/test_window_info.py +29 -0
- kivy/tests/visual_test_label.py +291 -0
- kivy/tools/__init__.py +44 -0
- kivy/tools/benchmark.py +286 -0
- kivy/tools/changelog_parser.py +120 -0
- kivy/tools/coverage.py +135 -0
- kivy/tools/gallery.py +323 -0
- kivy/tools/generate-icons.py +117 -0
- kivy/tools/gles_compat/subset_gles.py +125 -0
- kivy/tools/highlight/__init__.py +9 -0
- kivy/tools/kviewer.py +80 -0
- kivy/tools/packaging/__init__.py +12 -0
- kivy/tools/packaging/cython_cfg.py +82 -0
- kivy/tools/packaging/factory.py +105 -0
- kivy/tools/packaging/pyinstaller_hooks/__init__.py +381 -0
- kivy/tools/packaging/pyinstaller_hooks/__main__.py +29 -0
- kivy/tools/packaging/pyinstaller_hooks/hook-kivy.py +9 -0
- kivy/tools/packaging/pyinstaller_hooks/pyi_rth_kivy.py +17 -0
- kivy/tools/pep8checker/pep8.py +2316 -0
- kivy/tools/pep8checker/pep8kivy.py +109 -0
- kivy/tools/report.py +223 -0
- kivy/tools/stub-gl-debug.py +201 -0
- kivy/tools/texturecompress.py +233 -0
- kivy/uix/__init__.py +56 -0
- kivy/uix/accordion.py +484 -0
- kivy/uix/actionbar.py +934 -0
- kivy/uix/anchorlayout.py +122 -0
- kivy/uix/behaviors/__init__.py +95 -0
- kivy/uix/behaviors/button.py +212 -0
- kivy/uix/behaviors/codenavigation.py +167 -0
- kivy/uix/behaviors/compoundselection.py +688 -0
- kivy/uix/behaviors/cover.py +160 -0
- kivy/uix/behaviors/drag.py +234 -0
- kivy/uix/behaviors/emacs.py +140 -0
- kivy/uix/behaviors/focus.py +595 -0
- kivy/uix/behaviors/knspace.py +590 -0
- kivy/uix/behaviors/togglebutton.py +156 -0
- kivy/uix/behaviors/touchripple.py +318 -0
- kivy/uix/boxlayout.py +331 -0
- kivy/uix/bubble.py +576 -0
- kivy/uix/button.py +137 -0
- kivy/uix/camera.py +118 -0
- kivy/uix/carousel.py +695 -0
- kivy/uix/checkbox.py +197 -0
- kivy/uix/codeinput.py +238 -0
- kivy/uix/colorpicker.py +486 -0
- kivy/uix/dropdown.py +391 -0
- kivy/uix/effectwidget.py +772 -0
- kivy/uix/filechooser.py +1134 -0
- kivy/uix/floatlayout.py +148 -0
- kivy/uix/gesturesurface.py +625 -0
- kivy/uix/gridlayout.py +629 -0
- kivy/uix/image.py +528 -0
- kivy/uix/label.py +1200 -0
- kivy/uix/layout.py +322 -0
- kivy/uix/modalview.py +339 -0
- kivy/uix/pagelayout.py +233 -0
- kivy/uix/popup.py +266 -0
- kivy/uix/progressbar.py +95 -0
- kivy/uix/recycleboxlayout.py +183 -0
- kivy/uix/recyclegridlayout.py +255 -0
- kivy/uix/recyclelayout.py +446 -0
- kivy/uix/recycleview/__init__.py +624 -0
- kivy/uix/recycleview/datamodel.py +194 -0
- kivy/uix/recycleview/layout.py +253 -0
- kivy/uix/recycleview/views.py +423 -0
- kivy/uix/relativelayout.py +324 -0
- kivy/uix/rst.py +1492 -0
- kivy/uix/sandbox.py +198 -0
- kivy/uix/scatter.py +645 -0
- kivy/uix/scatterlayout.py +93 -0
- kivy/uix/screenmanager.py +1275 -0
- kivy/uix/scrollview.py +1288 -0
- kivy/uix/settings.py +1343 -0
- kivy/uix/slider.py +421 -0
- kivy/uix/spinner.py +221 -0
- kivy/uix/splitter.py +430 -0
- kivy/uix/stacklayout.py +331 -0
- kivy/uix/stencilview.py +40 -0
- kivy/uix/switch.py +122 -0
- kivy/uix/tabbedpanel.py +880 -0
- kivy/uix/textinput.py +4049 -0
- kivy/uix/togglebutton.py +37 -0
- kivy/uix/treeview.py +665 -0
- kivy/uix/video.py +302 -0
- kivy/uix/videoplayer.py +697 -0
- kivy/uix/vkeyboard.py +879 -0
- kivy/uix/widget.py +1629 -0
- kivy/utils.py +550 -0
- kivy/vector.py +412 -0
- kivy/weakmethod.py +72 -0
|
@@ -0,0 +1,996 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Image
|
|
3
|
+
=====
|
|
4
|
+
|
|
5
|
+
Core classes for loading images and converting them to a
|
|
6
|
+
:class:`~kivy.graphics.texture.Texture`. The raw image data can be keep in
|
|
7
|
+
memory for further access.
|
|
8
|
+
|
|
9
|
+
.. versionchanged:: 1.11.0
|
|
10
|
+
|
|
11
|
+
Add support for argb and abgr image data
|
|
12
|
+
|
|
13
|
+
In-memory image loading
|
|
14
|
+
-----------------------
|
|
15
|
+
|
|
16
|
+
.. versionadded:: 1.9.0
|
|
17
|
+
|
|
18
|
+
Official support for in-memory loading. Not all the providers support it,
|
|
19
|
+
but currently SDL2, pygame, pil and imageio work.
|
|
20
|
+
|
|
21
|
+
To load an image with a filename, you would usually do::
|
|
22
|
+
|
|
23
|
+
from kivy.core.image import Image as CoreImage
|
|
24
|
+
im = CoreImage("image.png")
|
|
25
|
+
|
|
26
|
+
You can also load the image data directly from a memory block. Instead of
|
|
27
|
+
passing the filename, you'll need to pass the data as a BytesIO object
|
|
28
|
+
together with an "ext" parameter. Both are mandatory::
|
|
29
|
+
|
|
30
|
+
import io
|
|
31
|
+
from kivy.core.image import Image as CoreImage
|
|
32
|
+
data = io.BytesIO(open("image.png", "rb").read())
|
|
33
|
+
im = CoreImage(data, ext="png")
|
|
34
|
+
|
|
35
|
+
By default, the image will not be cached as our internal cache requires a
|
|
36
|
+
filename. If you want caching, add a filename that represents your file (it
|
|
37
|
+
will be used only for caching)::
|
|
38
|
+
|
|
39
|
+
import io
|
|
40
|
+
from kivy.core.image import Image as CoreImage
|
|
41
|
+
data = io.BytesIO(open("image.png", "rb").read())
|
|
42
|
+
im = CoreImage(data, ext="png", filename="image.png")
|
|
43
|
+
|
|
44
|
+
Saving an image
|
|
45
|
+
---------------
|
|
46
|
+
|
|
47
|
+
A CoreImage can be saved to a file::
|
|
48
|
+
|
|
49
|
+
from kivy.core.image import Image as CoreImage
|
|
50
|
+
image = CoreImage(...)
|
|
51
|
+
image.save("/tmp/test.png")
|
|
52
|
+
|
|
53
|
+
Or you can get the bytes (new in `1.11.0`):
|
|
54
|
+
|
|
55
|
+
import io
|
|
56
|
+
from kivy.core.image import Image as CoreImage
|
|
57
|
+
data = io.BytesIO()
|
|
58
|
+
image = CoreImage(...)
|
|
59
|
+
image.save(data, fmt="png")
|
|
60
|
+
png_bytes = data.read()
|
|
61
|
+
|
|
62
|
+
'''
|
|
63
|
+
import re
|
|
64
|
+
from base64 import b64decode
|
|
65
|
+
from filetype import guess_extension
|
|
66
|
+
|
|
67
|
+
__all__ = ('Image', 'ImageLoader', 'ImageData')
|
|
68
|
+
|
|
69
|
+
from kivy.event import EventDispatcher
|
|
70
|
+
from kivy.core import core_register_libs
|
|
71
|
+
from kivy.logger import Logger
|
|
72
|
+
from kivy.cache import Cache
|
|
73
|
+
from kivy.clock import Clock
|
|
74
|
+
from kivy.atlas import Atlas
|
|
75
|
+
from kivy.resources import resource_find
|
|
76
|
+
from kivy.utils import platform
|
|
77
|
+
from kivy.compat import string_types
|
|
78
|
+
from kivy.setupconfig import USE_SDL2
|
|
79
|
+
import zipfile
|
|
80
|
+
from io import BytesIO
|
|
81
|
+
|
|
82
|
+
# late binding
|
|
83
|
+
Texture = TextureRegion = None
|
|
84
|
+
|
|
85
|
+
# register image caching only for keep_data=True
|
|
86
|
+
Cache.register('kv.image', timeout=60)
|
|
87
|
+
Cache.register('kv.atlas')
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ImageData(object):
|
|
91
|
+
'''Container for images and mipmap images.
|
|
92
|
+
The container will always have at least the mipmap level 0.
|
|
93
|
+
'''
|
|
94
|
+
|
|
95
|
+
__slots__ = ('fmt', 'mipmaps', 'source', 'flip_vertical', 'source_image')
|
|
96
|
+
_supported_fmts = ('rgb', 'bgr', 'rgba', 'bgra', 'argb', 'abgr',
|
|
97
|
+
's3tc_dxt1', 's3tc_dxt3', 's3tc_dxt5', 'pvrtc_rgb2',
|
|
98
|
+
'pvrtc_rgb4', 'pvrtc_rgba2', 'pvrtc_rgba4', 'etc1_rgb8')
|
|
99
|
+
|
|
100
|
+
def __init__(self, width, height, fmt, data, source=None,
|
|
101
|
+
flip_vertical=True, source_image=None,
|
|
102
|
+
rowlength=0):
|
|
103
|
+
assert fmt in ImageData._supported_fmts
|
|
104
|
+
|
|
105
|
+
#: Decoded image format, one of a available texture format
|
|
106
|
+
self.fmt = fmt
|
|
107
|
+
|
|
108
|
+
#: Data for each mipmap.
|
|
109
|
+
self.mipmaps = {}
|
|
110
|
+
self.add_mipmap(0, width, height, data, rowlength)
|
|
111
|
+
|
|
112
|
+
#: Image source, if available
|
|
113
|
+
self.source = source
|
|
114
|
+
|
|
115
|
+
#: Indicate if the texture will need to be vertically flipped
|
|
116
|
+
self.flip_vertical = flip_vertical
|
|
117
|
+
|
|
118
|
+
# the original image, which we might need to save if it is a memoryview
|
|
119
|
+
self.source_image = source_image
|
|
120
|
+
|
|
121
|
+
def release_data(self):
|
|
122
|
+
mm = self.mipmaps
|
|
123
|
+
for item in mm.values():
|
|
124
|
+
item[2] = None
|
|
125
|
+
self.source_image = None
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def width(self):
|
|
129
|
+
'''Image width in pixels.
|
|
130
|
+
(If the image is mipmapped, it will use the level 0)
|
|
131
|
+
'''
|
|
132
|
+
return self.mipmaps[0][0]
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def height(self):
|
|
136
|
+
'''Image height in pixels.
|
|
137
|
+
(If the image is mipmapped, it will use the level 0)
|
|
138
|
+
'''
|
|
139
|
+
return self.mipmaps[0][1]
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def data(self):
|
|
143
|
+
'''Image data.
|
|
144
|
+
(If the image is mipmapped, it will use the level 0)
|
|
145
|
+
'''
|
|
146
|
+
return self.mipmaps[0][2]
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def rowlength(self):
|
|
150
|
+
'''Image rowlength.
|
|
151
|
+
(If the image is mipmapped, it will use the level 0)
|
|
152
|
+
|
|
153
|
+
.. versionadded:: 1.9.0
|
|
154
|
+
'''
|
|
155
|
+
return self.mipmaps[0][3]
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def size(self):
|
|
159
|
+
'''Image (width, height) in pixels.
|
|
160
|
+
(If the image is mipmapped, it will use the level 0)
|
|
161
|
+
'''
|
|
162
|
+
mm = self.mipmaps[0]
|
|
163
|
+
return mm[0], mm[1]
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def have_mipmap(self):
|
|
167
|
+
return len(self.mipmaps) > 1
|
|
168
|
+
|
|
169
|
+
def __repr__(self):
|
|
170
|
+
return ('<ImageData width=%d height=%d fmt=%s '
|
|
171
|
+
'source=%r with %d images>' % (
|
|
172
|
+
self.width, self.height, self.fmt,
|
|
173
|
+
self.source, len(self.mipmaps)))
|
|
174
|
+
|
|
175
|
+
def add_mipmap(self, level, width, height, data, rowlength):
|
|
176
|
+
'''Add a image for a specific mipmap level.
|
|
177
|
+
|
|
178
|
+
.. versionadded:: 1.0.7
|
|
179
|
+
'''
|
|
180
|
+
self.mipmaps[level] = [int(width), int(height), data, rowlength]
|
|
181
|
+
|
|
182
|
+
def get_mipmap(self, level):
|
|
183
|
+
'''Get the mipmap image at a specific level if it exists
|
|
184
|
+
|
|
185
|
+
.. versionadded:: 1.0.7
|
|
186
|
+
'''
|
|
187
|
+
if level == 0:
|
|
188
|
+
return self.width, self.height, self.data, self.rowlength
|
|
189
|
+
assert level < len(self.mipmaps)
|
|
190
|
+
return self.mipmaps[level]
|
|
191
|
+
|
|
192
|
+
def iterate_mipmaps(self):
|
|
193
|
+
'''Iterate over all mipmap images available.
|
|
194
|
+
|
|
195
|
+
.. versionadded:: 1.0.7
|
|
196
|
+
'''
|
|
197
|
+
mm = self.mipmaps
|
|
198
|
+
for x in range(len(mm)):
|
|
199
|
+
item = mm.get(x, None)
|
|
200
|
+
if item is None:
|
|
201
|
+
raise Exception('Invalid mipmap level, found empty one')
|
|
202
|
+
yield x, item[0], item[1], item[2], item[3]
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class ImageLoaderBase(object):
|
|
206
|
+
'''Base to implement an image loader.'''
|
|
207
|
+
|
|
208
|
+
__slots__ = ('_texture', '_data', 'filename', 'keep_data',
|
|
209
|
+
'_mipmap', '_nocache', '_ext', '_inline')
|
|
210
|
+
|
|
211
|
+
def __init__(self, filename, **kwargs):
|
|
212
|
+
self._mipmap = kwargs.get('mipmap', False)
|
|
213
|
+
self.keep_data = kwargs.get('keep_data', False)
|
|
214
|
+
self._nocache = kwargs.get('nocache', False)
|
|
215
|
+
self._ext = kwargs.get('ext')
|
|
216
|
+
self._inline = kwargs.get('inline')
|
|
217
|
+
self.filename = filename
|
|
218
|
+
if self._inline:
|
|
219
|
+
self._data = self.load(kwargs.get('rawdata'))
|
|
220
|
+
else:
|
|
221
|
+
self._data = self.load(filename)
|
|
222
|
+
self._textures = None
|
|
223
|
+
|
|
224
|
+
def load(self, filename):
|
|
225
|
+
'''Load an image'''
|
|
226
|
+
return None
|
|
227
|
+
|
|
228
|
+
@staticmethod
|
|
229
|
+
def can_save(fmt, is_bytesio=False):
|
|
230
|
+
'''Indicate if the loader can save the Image object
|
|
231
|
+
|
|
232
|
+
.. versionchanged:: 1.11.0
|
|
233
|
+
Parameter `fmt` and `is_bytesio` added
|
|
234
|
+
'''
|
|
235
|
+
return False
|
|
236
|
+
|
|
237
|
+
@staticmethod
|
|
238
|
+
def can_load_memory():
|
|
239
|
+
'''Indicate if the loader can load an image by passing data
|
|
240
|
+
'''
|
|
241
|
+
return False
|
|
242
|
+
|
|
243
|
+
@staticmethod
|
|
244
|
+
def save(*largs, **kwargs):
|
|
245
|
+
raise NotImplementedError()
|
|
246
|
+
|
|
247
|
+
def populate(self):
|
|
248
|
+
self._textures = []
|
|
249
|
+
fname = self.filename
|
|
250
|
+
if __debug__:
|
|
251
|
+
Logger.trace('Image: %r, populate to textures (%d)' %
|
|
252
|
+
(fname, len(self._data)))
|
|
253
|
+
|
|
254
|
+
for count in range(len(self._data)):
|
|
255
|
+
|
|
256
|
+
# first, check if a texture with the same name already exist in the
|
|
257
|
+
# cache
|
|
258
|
+
uid = f'{fname}|{self._mipmap:d}|{count:d}'
|
|
259
|
+
texture = Cache.get('kv.texture', uid)
|
|
260
|
+
|
|
261
|
+
# if not create it and append to the cache
|
|
262
|
+
if texture is None:
|
|
263
|
+
imagedata = self._data[count]
|
|
264
|
+
source = (f"{'zip|' if fname.endswith('.zip') else ''}"
|
|
265
|
+
f"{self._nocache}|")
|
|
266
|
+
imagedata.source = f'{source}{uid}'
|
|
267
|
+
texture = Texture.create_from_data(
|
|
268
|
+
imagedata, mipmap=self._mipmap)
|
|
269
|
+
if not self._nocache:
|
|
270
|
+
Cache.append('kv.texture', uid, texture)
|
|
271
|
+
if imagedata.flip_vertical:
|
|
272
|
+
texture.flip_vertical()
|
|
273
|
+
|
|
274
|
+
# set as our current texture
|
|
275
|
+
self._textures.append(texture)
|
|
276
|
+
|
|
277
|
+
# release data if ask
|
|
278
|
+
if not self.keep_data:
|
|
279
|
+
self._data[count].release_data()
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def width(self):
|
|
283
|
+
'''Image width
|
|
284
|
+
'''
|
|
285
|
+
return self._data[0].width
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
def height(self):
|
|
289
|
+
'''Image height
|
|
290
|
+
'''
|
|
291
|
+
return self._data[0].height
|
|
292
|
+
|
|
293
|
+
@property
|
|
294
|
+
def size(self):
|
|
295
|
+
'''Image size (width, height)
|
|
296
|
+
'''
|
|
297
|
+
return self._data[0].width, self._data[0].height
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def texture(self):
|
|
301
|
+
'''Get the image texture (created on the first call)
|
|
302
|
+
'''
|
|
303
|
+
if self._textures is None:
|
|
304
|
+
self.populate()
|
|
305
|
+
if self._textures is None:
|
|
306
|
+
return None
|
|
307
|
+
return self._textures[0]
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
def textures(self):
|
|
311
|
+
'''Get the textures list (for mipmapped image or animated image)
|
|
312
|
+
|
|
313
|
+
.. versionadded:: 1.0.8
|
|
314
|
+
'''
|
|
315
|
+
if self._textures is None:
|
|
316
|
+
self.populate()
|
|
317
|
+
return self._textures
|
|
318
|
+
|
|
319
|
+
@property
|
|
320
|
+
def nocache(self):
|
|
321
|
+
'''Indicate if the texture will not be stored in the cache
|
|
322
|
+
|
|
323
|
+
.. versionadded:: 1.6.0
|
|
324
|
+
'''
|
|
325
|
+
return self._nocache
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
class ImageLoader(object):
|
|
329
|
+
loaders = []
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
def zip_loader(filename, **kwargs):
|
|
333
|
+
'''Read images from an zip file.
|
|
334
|
+
|
|
335
|
+
.. versionadded:: 1.0.8
|
|
336
|
+
|
|
337
|
+
Returns an Image with a list of type ImageData stored in Image._data
|
|
338
|
+
'''
|
|
339
|
+
# read zip in memory for faster access
|
|
340
|
+
_file = BytesIO(open(filename, 'rb').read())
|
|
341
|
+
# read all images inside the zip
|
|
342
|
+
z = zipfile.ZipFile(_file)
|
|
343
|
+
image_data = []
|
|
344
|
+
# sort filename list
|
|
345
|
+
znamelist = z.namelist()
|
|
346
|
+
znamelist.sort()
|
|
347
|
+
image = None
|
|
348
|
+
for zfilename in znamelist:
|
|
349
|
+
try:
|
|
350
|
+
# read file and store it in mem with fileIO struct around it
|
|
351
|
+
tmpfile = BytesIO(z.read(zfilename))
|
|
352
|
+
ext = zfilename.split('.')[-1].lower()
|
|
353
|
+
im = None
|
|
354
|
+
for loader in ImageLoader.loaders:
|
|
355
|
+
if (ext not in loader.extensions() or
|
|
356
|
+
not loader.can_load_memory()):
|
|
357
|
+
continue
|
|
358
|
+
Logger.debug('Image%s: Load <%s> from <%s>' %
|
|
359
|
+
(loader.__name__[11:], zfilename, filename))
|
|
360
|
+
try:
|
|
361
|
+
im = loader(zfilename, ext=ext, rawdata=tmpfile,
|
|
362
|
+
inline=True, **kwargs)
|
|
363
|
+
except:
|
|
364
|
+
# Loader failed, continue trying.
|
|
365
|
+
continue
|
|
366
|
+
break
|
|
367
|
+
if im is not None:
|
|
368
|
+
# append ImageData to local variable before its
|
|
369
|
+
# overwritten
|
|
370
|
+
image_data.append(im._data[0])
|
|
371
|
+
image = im
|
|
372
|
+
# else: if not image file skip to next
|
|
373
|
+
except:
|
|
374
|
+
Logger.warning('Image: Unable to load image'
|
|
375
|
+
'<%s> in zip <%s> trying to continue...'
|
|
376
|
+
% (zfilename, filename))
|
|
377
|
+
z.close()
|
|
378
|
+
if len(image_data) == 0:
|
|
379
|
+
raise Exception('no images in zip <%s>' % filename)
|
|
380
|
+
# replace Image.Data with the array of all the images in the zip
|
|
381
|
+
image._data = image_data
|
|
382
|
+
image.filename = filename
|
|
383
|
+
return image
|
|
384
|
+
|
|
385
|
+
@staticmethod
|
|
386
|
+
def register(defcls):
|
|
387
|
+
ImageLoader.loaders.append(defcls)
|
|
388
|
+
|
|
389
|
+
@staticmethod
|
|
390
|
+
def load(filename, **kwargs):
|
|
391
|
+
|
|
392
|
+
# atlas ?
|
|
393
|
+
if filename[:8] == 'atlas://':
|
|
394
|
+
# remove the url
|
|
395
|
+
rfn = filename[8:]
|
|
396
|
+
# last field is the ID
|
|
397
|
+
try:
|
|
398
|
+
rfn, uid = rfn.rsplit('/', 1)
|
|
399
|
+
except ValueError:
|
|
400
|
+
raise ValueError(
|
|
401
|
+
'Image: Invalid %s name for atlas' % filename)
|
|
402
|
+
|
|
403
|
+
# search if we already got the atlas loaded
|
|
404
|
+
atlas = Cache.get('kv.atlas', rfn)
|
|
405
|
+
|
|
406
|
+
# atlas already loaded, so reupload the missing texture in cache,
|
|
407
|
+
# because when it's not in use, the texture can be removed from the
|
|
408
|
+
# kv.texture cache.
|
|
409
|
+
if atlas:
|
|
410
|
+
texture = atlas[uid]
|
|
411
|
+
fn = f'atlas://{rfn}/{uid}'
|
|
412
|
+
cid = f'{fn}|0|0'
|
|
413
|
+
Cache.append('kv.texture', cid, texture)
|
|
414
|
+
return Image(texture)
|
|
415
|
+
|
|
416
|
+
# search with resource
|
|
417
|
+
afn = rfn
|
|
418
|
+
if not afn.endswith('.atlas'):
|
|
419
|
+
afn += '.atlas'
|
|
420
|
+
afn = resource_find(afn)
|
|
421
|
+
if not afn:
|
|
422
|
+
raise Exception('Unable to find %r atlas' % afn)
|
|
423
|
+
atlas = Atlas(afn)
|
|
424
|
+
Cache.append('kv.atlas', rfn, atlas)
|
|
425
|
+
# first time, fill our texture cache.
|
|
426
|
+
for nid, texture in atlas.textures.items():
|
|
427
|
+
fn = f'atlas://{rfn}/{nid}'
|
|
428
|
+
cid = f'{fn}|0|0'
|
|
429
|
+
Cache.append('kv.texture', cid, texture)
|
|
430
|
+
return Image(atlas[uid])
|
|
431
|
+
|
|
432
|
+
# extract extensions
|
|
433
|
+
ext = filename.split('.')[-1].lower()
|
|
434
|
+
|
|
435
|
+
# prevent url querystrings
|
|
436
|
+
if filename.startswith(('http://', 'https://')):
|
|
437
|
+
ext = ext.split('?')[0]
|
|
438
|
+
|
|
439
|
+
filename = resource_find(filename)
|
|
440
|
+
|
|
441
|
+
# Get actual image format instead of extension if possible
|
|
442
|
+
ext = guess_extension(filename) or ext
|
|
443
|
+
|
|
444
|
+
# special case. When we are trying to load a "zip" file with image, we
|
|
445
|
+
# will use the special zip_loader in ImageLoader. This might return a
|
|
446
|
+
# sequence of images contained in the zip.
|
|
447
|
+
if ext == 'zip':
|
|
448
|
+
return ImageLoader.zip_loader(filename)
|
|
449
|
+
else:
|
|
450
|
+
im = None
|
|
451
|
+
for loader in ImageLoader.loaders:
|
|
452
|
+
if ext not in loader.extensions():
|
|
453
|
+
continue
|
|
454
|
+
Logger.debug(f'Image{loader.__name__[11:]}: Load <{filename}>')
|
|
455
|
+
im = loader(filename, **kwargs)
|
|
456
|
+
break
|
|
457
|
+
if im is None:
|
|
458
|
+
raise Exception(f'Unknown <{ext}> type, no loader found.')
|
|
459
|
+
return im
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
class Image(EventDispatcher):
|
|
463
|
+
'''Load an image and store the size and texture.
|
|
464
|
+
|
|
465
|
+
.. versionchanged:: 1.0.7
|
|
466
|
+
|
|
467
|
+
`mipmap` attribute has been added. The `texture_mipmap` and
|
|
468
|
+
`texture_rectangle` have been deleted.
|
|
469
|
+
|
|
470
|
+
.. versionchanged:: 1.0.8
|
|
471
|
+
|
|
472
|
+
An Image widget can change its texture. A new event 'on_texture' has
|
|
473
|
+
been introduced. New methods for handling sequenced animation have been
|
|
474
|
+
added.
|
|
475
|
+
|
|
476
|
+
:Parameters:
|
|
477
|
+
`arg`: can be a string (str), Texture, BytesIO or Image object
|
|
478
|
+
A string path to the image file or data URI to be loaded; or a
|
|
479
|
+
Texture object, which will be wrapped in an Image object; or a
|
|
480
|
+
BytesIO object containing raw image data; or an already existing
|
|
481
|
+
image object, in which case, a real copy of the given image object
|
|
482
|
+
will be returned.
|
|
483
|
+
`keep_data`: bool, defaults to False
|
|
484
|
+
Keep the image data when the texture is created.
|
|
485
|
+
`mipmap`: bool, defaults to False
|
|
486
|
+
Create mipmap for the texture.
|
|
487
|
+
`anim_delay`: float, defaults to .25
|
|
488
|
+
Delay in seconds between each animation frame. Lower values means
|
|
489
|
+
faster animation.
|
|
490
|
+
`ext`: str, only with BytesIO `arg`
|
|
491
|
+
File extension to use in determining how to load raw image data.
|
|
492
|
+
`filename`: str, only with BytesIO `arg`
|
|
493
|
+
Filename to use in the image cache for raw image data.
|
|
494
|
+
'''
|
|
495
|
+
|
|
496
|
+
copy_attributes = ('_size', '_filename', '_texture', '_image',
|
|
497
|
+
'_mipmap', '_nocache')
|
|
498
|
+
|
|
499
|
+
data_uri_re = re.compile(r'^data:image/([^;,]*)(;[^,]*)?,(.*)$')
|
|
500
|
+
|
|
501
|
+
_anim_ev = None
|
|
502
|
+
|
|
503
|
+
def __init__(self, arg, **kwargs):
|
|
504
|
+
# this event should be fired on animation of sequenced img's
|
|
505
|
+
self.register_event_type('on_texture')
|
|
506
|
+
|
|
507
|
+
super(Image, self).__init__()
|
|
508
|
+
|
|
509
|
+
self._mipmap = kwargs.get('mipmap', False)
|
|
510
|
+
self._keep_data = kwargs.get('keep_data', False)
|
|
511
|
+
self._nocache = kwargs.get('nocache', False)
|
|
512
|
+
self._size = [0, 0]
|
|
513
|
+
self._image = None
|
|
514
|
+
self._filename = None
|
|
515
|
+
self._texture = None
|
|
516
|
+
self._anim_available = False
|
|
517
|
+
self._anim_index = 0
|
|
518
|
+
self._anim_delay = 0
|
|
519
|
+
self.anim_delay = kwargs.get('anim_delay', .25)
|
|
520
|
+
# indicator of images having been loded in cache
|
|
521
|
+
self._iteration_done = False
|
|
522
|
+
|
|
523
|
+
if isinstance(arg, Image):
|
|
524
|
+
for attr in Image.copy_attributes:
|
|
525
|
+
self.__setattr__(attr, arg.__getattribute__(attr))
|
|
526
|
+
elif type(arg) in (Texture, TextureRegion):
|
|
527
|
+
if not hasattr(self, 'textures'):
|
|
528
|
+
self.textures = []
|
|
529
|
+
self.textures.append(arg)
|
|
530
|
+
self._texture = arg
|
|
531
|
+
self._size = self.texture.size
|
|
532
|
+
elif isinstance(arg, ImageLoaderBase):
|
|
533
|
+
self.image = arg
|
|
534
|
+
elif isinstance(arg, BytesIO):
|
|
535
|
+
ext = kwargs.get('ext', None)
|
|
536
|
+
if not ext:
|
|
537
|
+
raise Exception('Inline loading require "ext" parameter')
|
|
538
|
+
filename = kwargs.get('filename')
|
|
539
|
+
if not filename:
|
|
540
|
+
self._nocache = True
|
|
541
|
+
filename = '__inline__'
|
|
542
|
+
self.load_memory(arg, ext, filename)
|
|
543
|
+
elif isinstance(arg, string_types):
|
|
544
|
+
groups = self.data_uri_re.findall(arg)
|
|
545
|
+
if groups:
|
|
546
|
+
self._nocache = True
|
|
547
|
+
imtype, optstr, data = groups[0]
|
|
548
|
+
options = [o for o in optstr.split(';') if o]
|
|
549
|
+
ext = imtype
|
|
550
|
+
isb64 = 'base64' in options
|
|
551
|
+
if data:
|
|
552
|
+
if isb64:
|
|
553
|
+
data = b64decode(data)
|
|
554
|
+
self.load_memory(BytesIO(data), ext)
|
|
555
|
+
else:
|
|
556
|
+
self.filename = arg
|
|
557
|
+
else:
|
|
558
|
+
raise Exception('Unable to load image type {0!r}'.format(arg))
|
|
559
|
+
|
|
560
|
+
def remove_from_cache(self):
|
|
561
|
+
'''Remove the Image from cache. This facilitates re-loading of
|
|
562
|
+
images from disk in case the image content has changed.
|
|
563
|
+
|
|
564
|
+
.. versionadded:: 1.3.0
|
|
565
|
+
|
|
566
|
+
Usage::
|
|
567
|
+
|
|
568
|
+
im = CoreImage('1.jpg')
|
|
569
|
+
# -- do something --
|
|
570
|
+
im.remove_from_cache()
|
|
571
|
+
im = CoreImage('1.jpg')
|
|
572
|
+
# this time image will be re-loaded from disk
|
|
573
|
+
|
|
574
|
+
'''
|
|
575
|
+
count = 0
|
|
576
|
+
uid = f'{self.filename}|{self._mipmap:d}|{count:d}'
|
|
577
|
+
Cache.remove("kv.image", uid)
|
|
578
|
+
while Cache.get("kv.texture", uid):
|
|
579
|
+
Cache.remove("kv.texture", uid)
|
|
580
|
+
count += 1
|
|
581
|
+
uid = f'{self.filename}|{self._mipmap:d}|{count:d}'
|
|
582
|
+
|
|
583
|
+
def _anim(self, *largs):
|
|
584
|
+
if not self._image:
|
|
585
|
+
return
|
|
586
|
+
textures = self.image.textures
|
|
587
|
+
if self._anim_index >= len(textures):
|
|
588
|
+
self._anim_index = 0
|
|
589
|
+
self._texture = self.image.textures[self._anim_index]
|
|
590
|
+
self.dispatch('on_texture')
|
|
591
|
+
self._anim_index += 1
|
|
592
|
+
self._anim_index %= len(self._image.textures)
|
|
593
|
+
|
|
594
|
+
def anim_reset(self, allow_anim):
|
|
595
|
+
'''Reset an animation if available.
|
|
596
|
+
|
|
597
|
+
.. versionadded:: 1.0.8
|
|
598
|
+
|
|
599
|
+
:Parameters:
|
|
600
|
+
`allow_anim`: bool
|
|
601
|
+
Indicate whether the animation should restart playing or not.
|
|
602
|
+
|
|
603
|
+
Usage::
|
|
604
|
+
|
|
605
|
+
# start/reset animation
|
|
606
|
+
image.anim_reset(True)
|
|
607
|
+
|
|
608
|
+
# or stop the animation
|
|
609
|
+
image.anim_reset(False)
|
|
610
|
+
|
|
611
|
+
You can change the animation speed whilst it is playing::
|
|
612
|
+
|
|
613
|
+
# Set to 20 FPS
|
|
614
|
+
image.anim_delay = 1 / 20.
|
|
615
|
+
|
|
616
|
+
'''
|
|
617
|
+
# stop animation
|
|
618
|
+
if self._anim_ev is not None:
|
|
619
|
+
self._anim_ev.cancel()
|
|
620
|
+
self._anim_ev = None
|
|
621
|
+
|
|
622
|
+
if allow_anim and self._anim_available and self._anim_delay >= 0:
|
|
623
|
+
self._anim_ev = Clock.schedule_interval(self._anim,
|
|
624
|
+
self.anim_delay)
|
|
625
|
+
self._anim()
|
|
626
|
+
|
|
627
|
+
def _get_anim_delay(self):
|
|
628
|
+
return self._anim_delay
|
|
629
|
+
|
|
630
|
+
def _set_anim_delay(self, x):
|
|
631
|
+
if self._anim_delay == x:
|
|
632
|
+
return
|
|
633
|
+
self._anim_delay = x
|
|
634
|
+
if self._anim_available:
|
|
635
|
+
if self._anim_ev is not None:
|
|
636
|
+
self._anim_ev.cancel()
|
|
637
|
+
self._anim_ev = None
|
|
638
|
+
|
|
639
|
+
if self._anim_delay >= 0:
|
|
640
|
+
self._anim_ev = Clock.schedule_interval(self._anim,
|
|
641
|
+
self._anim_delay)
|
|
642
|
+
|
|
643
|
+
anim_delay = property(_get_anim_delay, _set_anim_delay)
|
|
644
|
+
'''Delay between each animation frame. A lower value means faster
|
|
645
|
+
animation.
|
|
646
|
+
|
|
647
|
+
.. versionadded:: 1.0.8
|
|
648
|
+
'''
|
|
649
|
+
|
|
650
|
+
@property
|
|
651
|
+
def anim_available(self):
|
|
652
|
+
'''Return True if this Image instance has animation available.
|
|
653
|
+
|
|
654
|
+
.. versionadded:: 1.0.8
|
|
655
|
+
'''
|
|
656
|
+
return self._anim_available
|
|
657
|
+
|
|
658
|
+
@property
|
|
659
|
+
def anim_index(self):
|
|
660
|
+
'''Return the index number of the image currently in the texture.
|
|
661
|
+
|
|
662
|
+
.. versionadded:: 1.0.8
|
|
663
|
+
'''
|
|
664
|
+
return self._anim_index
|
|
665
|
+
|
|
666
|
+
def _img_iterate(self, *largs):
|
|
667
|
+
if not self.image or self._iteration_done:
|
|
668
|
+
return
|
|
669
|
+
self._iteration_done = True
|
|
670
|
+
imgcount = len(self.image.textures)
|
|
671
|
+
if imgcount > 1:
|
|
672
|
+
self._anim_available = True
|
|
673
|
+
self.anim_reset(True)
|
|
674
|
+
self._texture = self.image.textures[0]
|
|
675
|
+
|
|
676
|
+
def on_texture(self, *largs):
|
|
677
|
+
'''This event is fired when the texture reference or content has
|
|
678
|
+
changed. It is normally used for sequenced images.
|
|
679
|
+
|
|
680
|
+
.. versionadded:: 1.0.8
|
|
681
|
+
'''
|
|
682
|
+
pass
|
|
683
|
+
|
|
684
|
+
@staticmethod
|
|
685
|
+
def load(filename, **kwargs):
|
|
686
|
+
'''Load an image
|
|
687
|
+
|
|
688
|
+
:Parameters:
|
|
689
|
+
`filename`: str
|
|
690
|
+
Filename of the image.
|
|
691
|
+
`keep_data`: bool, defaults to False
|
|
692
|
+
Keep the image data when the texture is created.
|
|
693
|
+
'''
|
|
694
|
+
kwargs.setdefault('keep_data', False)
|
|
695
|
+
return Image(filename, **kwargs)
|
|
696
|
+
|
|
697
|
+
def _get_image(self):
|
|
698
|
+
return self._image
|
|
699
|
+
|
|
700
|
+
def _set_image(self, image):
|
|
701
|
+
self._image = image
|
|
702
|
+
if hasattr(image, 'filename'):
|
|
703
|
+
self._filename = image.filename
|
|
704
|
+
if image:
|
|
705
|
+
self._size = (self.image.width, self.image.height)
|
|
706
|
+
|
|
707
|
+
image = property(_get_image, _set_image,
|
|
708
|
+
doc='Get/set the data image object')
|
|
709
|
+
|
|
710
|
+
def _get_filename(self):
|
|
711
|
+
return self._filename
|
|
712
|
+
|
|
713
|
+
def _set_filename(self, value):
|
|
714
|
+
if value is None or value == self._filename:
|
|
715
|
+
return
|
|
716
|
+
self._filename = value
|
|
717
|
+
|
|
718
|
+
# construct uid as a key for Cache
|
|
719
|
+
f = self.filename
|
|
720
|
+
uid = f'{f}|{self._mipmap:d}|0'
|
|
721
|
+
|
|
722
|
+
# in case of Image have been asked with keep_data
|
|
723
|
+
# check the kv.image cache instead of texture.
|
|
724
|
+
image = Cache.get('kv.image', uid)
|
|
725
|
+
if image:
|
|
726
|
+
# we found an image, yeah ! but reset the texture now.
|
|
727
|
+
self.image = image
|
|
728
|
+
# if image.__class__ is core image then it's a texture
|
|
729
|
+
# from atlas or other sources and has no data so skip
|
|
730
|
+
if (image.__class__ != self.__class__ and
|
|
731
|
+
not image.keep_data and self._keep_data):
|
|
732
|
+
self.remove_from_cache()
|
|
733
|
+
self._filename = ''
|
|
734
|
+
self._set_filename(value)
|
|
735
|
+
else:
|
|
736
|
+
self._texture = None
|
|
737
|
+
return
|
|
738
|
+
else:
|
|
739
|
+
# if we already got a texture, it will be automatically reloaded.
|
|
740
|
+
_texture = Cache.get('kv.texture', uid)
|
|
741
|
+
if _texture:
|
|
742
|
+
self._texture = _texture
|
|
743
|
+
return
|
|
744
|
+
|
|
745
|
+
# if image not already in cache then load
|
|
746
|
+
tmpfilename = self._filename
|
|
747
|
+
image = ImageLoader.load(
|
|
748
|
+
self._filename, keep_data=self._keep_data,
|
|
749
|
+
mipmap=self._mipmap, nocache=self._nocache)
|
|
750
|
+
self._filename = tmpfilename
|
|
751
|
+
# put the image into the cache if needed
|
|
752
|
+
if isinstance(image, Texture):
|
|
753
|
+
self._texture = image
|
|
754
|
+
self._size = image.size
|
|
755
|
+
else:
|
|
756
|
+
self.image = image
|
|
757
|
+
if not self._nocache:
|
|
758
|
+
Cache.append('kv.image', uid, self.image)
|
|
759
|
+
|
|
760
|
+
filename = property(_get_filename, _set_filename,
|
|
761
|
+
doc='Get/set the filename of image')
|
|
762
|
+
|
|
763
|
+
def load_memory(self, data, ext, filename='__inline__'):
|
|
764
|
+
'''(internal) Method to load an image from raw data.
|
|
765
|
+
'''
|
|
766
|
+
self._filename = filename
|
|
767
|
+
|
|
768
|
+
# see if there is a available loader for it
|
|
769
|
+
loaders = [loader for loader in ImageLoader.loaders if
|
|
770
|
+
loader.can_load_memory() and
|
|
771
|
+
ext in loader.extensions()]
|
|
772
|
+
if not loaders:
|
|
773
|
+
raise Exception(f'No inline loader found to load {ext}')
|
|
774
|
+
image = loaders[0](filename, ext=ext, rawdata=data, inline=True,
|
|
775
|
+
nocache=self._nocache, mipmap=self._mipmap,
|
|
776
|
+
keep_data=self._keep_data)
|
|
777
|
+
if isinstance(image, Texture):
|
|
778
|
+
self._texture = image
|
|
779
|
+
self._size = image.size
|
|
780
|
+
else:
|
|
781
|
+
self.image = image
|
|
782
|
+
|
|
783
|
+
@property
|
|
784
|
+
def size(self):
|
|
785
|
+
'''Image size (width, height)
|
|
786
|
+
'''
|
|
787
|
+
return self._size
|
|
788
|
+
|
|
789
|
+
@property
|
|
790
|
+
def width(self):
|
|
791
|
+
'''Image width
|
|
792
|
+
'''
|
|
793
|
+
return self._size[0]
|
|
794
|
+
|
|
795
|
+
@property
|
|
796
|
+
def height(self):
|
|
797
|
+
'''Image height
|
|
798
|
+
'''
|
|
799
|
+
return self._size[1]
|
|
800
|
+
|
|
801
|
+
@property
|
|
802
|
+
def texture(self):
|
|
803
|
+
'''Texture of the image'''
|
|
804
|
+
if self.image:
|
|
805
|
+
if not self._iteration_done:
|
|
806
|
+
self._img_iterate()
|
|
807
|
+
return self._texture
|
|
808
|
+
|
|
809
|
+
@property
|
|
810
|
+
def nocache(self):
|
|
811
|
+
'''Indicate whether the texture will not be stored in the cache or not.
|
|
812
|
+
|
|
813
|
+
.. versionadded:: 1.6.0
|
|
814
|
+
'''
|
|
815
|
+
return self._nocache
|
|
816
|
+
|
|
817
|
+
def save(self, filename, flipped=False, fmt=None):
|
|
818
|
+
'''Save image texture to file.
|
|
819
|
+
|
|
820
|
+
The filename should have the '.png' extension because the texture data
|
|
821
|
+
read from the GPU is in the RGBA format. '.jpg' might work but has not
|
|
822
|
+
been heavily tested so some providers might break when using it.
|
|
823
|
+
Any other extensions are not officially supported.
|
|
824
|
+
|
|
825
|
+
The flipped parameter flips the saved image vertically, and
|
|
826
|
+
defaults to False.
|
|
827
|
+
|
|
828
|
+
Example::
|
|
829
|
+
|
|
830
|
+
# Save an core image object
|
|
831
|
+
from kivy.core.image import Image
|
|
832
|
+
img = Image('hello.png')
|
|
833
|
+
img.save('hello2.png')
|
|
834
|
+
|
|
835
|
+
# Save a texture
|
|
836
|
+
texture = Texture.create(...)
|
|
837
|
+
img = Image(texture)
|
|
838
|
+
img.save('hello3.png')
|
|
839
|
+
|
|
840
|
+
.. versionadded:: 1.7.0
|
|
841
|
+
|
|
842
|
+
.. versionchanged:: 1.8.0
|
|
843
|
+
Parameter `flipped` added to flip the image before saving, default
|
|
844
|
+
to False.
|
|
845
|
+
|
|
846
|
+
.. versionchanged:: 1.11.0
|
|
847
|
+
Parameter `fmt` added to force the output format of the file
|
|
848
|
+
Filename can now be a BytesIO object.
|
|
849
|
+
|
|
850
|
+
'''
|
|
851
|
+
is_bytesio = False
|
|
852
|
+
if isinstance(filename, BytesIO):
|
|
853
|
+
is_bytesio = True
|
|
854
|
+
if not fmt:
|
|
855
|
+
raise Exception(
|
|
856
|
+
"You must specify a format to save into a BytesIO object")
|
|
857
|
+
elif fmt is None:
|
|
858
|
+
fmt = self._find_format_from_filename(filename)
|
|
859
|
+
|
|
860
|
+
pixels = None
|
|
861
|
+
size = None
|
|
862
|
+
loaders = [
|
|
863
|
+
x for x in ImageLoader.loaders
|
|
864
|
+
if x.can_save(fmt, is_bytesio=is_bytesio)
|
|
865
|
+
]
|
|
866
|
+
if not loaders:
|
|
867
|
+
return False
|
|
868
|
+
loader = loaders[0]
|
|
869
|
+
|
|
870
|
+
if self.image:
|
|
871
|
+
# we might have a ImageData object to use
|
|
872
|
+
data = self.image._data[0]
|
|
873
|
+
if data.data is not None:
|
|
874
|
+
if data.fmt in ('rgba', 'rgb'):
|
|
875
|
+
# fast path, use the "raw" data when keep_data is used
|
|
876
|
+
size = data.width, data.height
|
|
877
|
+
pixels = data.data
|
|
878
|
+
|
|
879
|
+
else:
|
|
880
|
+
# the format is not rgba, we need to convert it.
|
|
881
|
+
# use texture for that.
|
|
882
|
+
self.populate()
|
|
883
|
+
|
|
884
|
+
if pixels is None and self._texture:
|
|
885
|
+
# use the texture pixels
|
|
886
|
+
size = self._texture.size
|
|
887
|
+
pixels = self._texture.pixels
|
|
888
|
+
|
|
889
|
+
if pixels is None:
|
|
890
|
+
return False
|
|
891
|
+
|
|
892
|
+
l_pixels = len(pixels)
|
|
893
|
+
if l_pixels == size[0] * size[1] * 3:
|
|
894
|
+
pixelfmt = 'rgb'
|
|
895
|
+
elif l_pixels == size[0] * size[1] * 4:
|
|
896
|
+
pixelfmt = 'rgba'
|
|
897
|
+
else:
|
|
898
|
+
raise Exception('Unable to determine the format of the pixels')
|
|
899
|
+
return loader.save(
|
|
900
|
+
filename, size[0], size[1], pixelfmt, pixels, flipped, fmt)
|
|
901
|
+
|
|
902
|
+
def _find_format_from_filename(self, filename):
|
|
903
|
+
ext = filename.rsplit(".", 1)[-1].lower()
|
|
904
|
+
if (ext in
|
|
905
|
+
{'bmp', 'jpe', 'lbm', 'pcx', 'png', 'pnm', 'tga',
|
|
906
|
+
'tiff', 'webp', 'xcf', 'xpm', 'xv'}):
|
|
907
|
+
return ext
|
|
908
|
+
elif ext in ('jpg', 'jpeg'):
|
|
909
|
+
return 'jpg'
|
|
910
|
+
elif ext in ('b64', 'base64'):
|
|
911
|
+
return 'base64'
|
|
912
|
+
return None
|
|
913
|
+
|
|
914
|
+
def read_pixel(self, x, y):
|
|
915
|
+
'''For a given local x/y position, return the pixel color at that
|
|
916
|
+
position.
|
|
917
|
+
|
|
918
|
+
.. warning::
|
|
919
|
+
This function can only be used with images loaded with the
|
|
920
|
+
keep_data=True keyword. For example::
|
|
921
|
+
|
|
922
|
+
m = Image.load('image.png', keep_data=True)
|
|
923
|
+
color = m.read_pixel(150, 150)
|
|
924
|
+
|
|
925
|
+
:Parameters:
|
|
926
|
+
`x`: int
|
|
927
|
+
Local x coordinate of the pixel in question.
|
|
928
|
+
`y`: int
|
|
929
|
+
Local y coordinate of the pixel in question.
|
|
930
|
+
'''
|
|
931
|
+
data = self.image._data[0]
|
|
932
|
+
|
|
933
|
+
# can't use this function without ImageData
|
|
934
|
+
if data.data is None:
|
|
935
|
+
raise EOFError('Image data is missing, make sure that image is'
|
|
936
|
+
'loaded with keep_data=True keyword.')
|
|
937
|
+
|
|
938
|
+
# check bounds
|
|
939
|
+
x, y = int(x), int(y)
|
|
940
|
+
if not (0 <= x < data.width and 0 <= y < data.height):
|
|
941
|
+
raise IndexError(f'Position ({x:d}, {y:d}) is out of range.')
|
|
942
|
+
|
|
943
|
+
assert data.fmt in ImageData._supported_fmts
|
|
944
|
+
size = 3 if data.fmt in ('rgb', 'bgr') else 4
|
|
945
|
+
index = y * data.width * size + x * size
|
|
946
|
+
raw = bytearray(data.data[index:index + size])
|
|
947
|
+
color = [c / 255.0 for c in raw]
|
|
948
|
+
|
|
949
|
+
bgr_flag = False
|
|
950
|
+
if data.fmt == 'argb':
|
|
951
|
+
color.reverse() # bgra
|
|
952
|
+
bgr_flag = True
|
|
953
|
+
elif data.fmt == 'abgr':
|
|
954
|
+
color.reverse() # rgba
|
|
955
|
+
|
|
956
|
+
# conversion for BGR->RGB, BGRA->RGBA format
|
|
957
|
+
if bgr_flag or data.fmt in ('bgr', 'bgra'):
|
|
958
|
+
color[0], color[2] = color[2], color[0]
|
|
959
|
+
|
|
960
|
+
return color
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
def load(filename):
|
|
964
|
+
'''Load an image'''
|
|
965
|
+
return Image.load(filename)
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
# load image loaders
|
|
969
|
+
image_libs = []
|
|
970
|
+
|
|
971
|
+
if platform in ('macosx', 'ios'):
|
|
972
|
+
image_libs += [('imageio', 'img_imageio')]
|
|
973
|
+
|
|
974
|
+
image_libs += [
|
|
975
|
+
('tex', 'img_tex'),
|
|
976
|
+
('dds', 'img_dds')]
|
|
977
|
+
if USE_SDL2:
|
|
978
|
+
image_libs += [('sdl2', 'img_sdl2')]
|
|
979
|
+
else:
|
|
980
|
+
image_libs += [('pygame', 'img_pygame')]
|
|
981
|
+
image_libs += [
|
|
982
|
+
('ffpy', 'img_ffpyplayer'),
|
|
983
|
+
('pil', 'img_pil')]
|
|
984
|
+
|
|
985
|
+
libs_loaded = core_register_libs('image', image_libs)
|
|
986
|
+
|
|
987
|
+
from os import environ
|
|
988
|
+
|
|
989
|
+
if 'KIVY_DOC' not in environ and not libs_loaded:
|
|
990
|
+
import sys
|
|
991
|
+
|
|
992
|
+
Logger.critical('App: Unable to get any Image provider, abort.')
|
|
993
|
+
sys.exit(1)
|
|
994
|
+
|
|
995
|
+
# resolve binding.
|
|
996
|
+
from kivy.graphics.texture import Texture, TextureRegion
|