Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GUI] Support saving image without GUI showing a window #1817

Merged
12 changes: 10 additions & 2 deletions python/taichi/misc/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ class Event:
PRESS = ti_core.KeyEvent.EType.Press
RELEASE = ti_core.KeyEvent.EType.Release

def __init__(self, name='Taichi', res=512, background_color=0x0):
def __init__(self,
name='Taichi',
show_GUI=True,
thinking-tower marked this conversation as resolved.
Show resolved Hide resolved
res=512,
background_color=0x0):
self.name = name
if isinstance(res, numbers.Number):
res = (res, res)
self.res = res
# The GUI canvas uses RGBA for storage, therefore we need NxMx4 for an image.
self.img = np.ascontiguousarray(np.zeros(self.res + (4, ), np.float32))
self.show_GUI = show_GUI
self.core = ti_core.GUI(name, core_veci(*res))
if self.show_GUI:
self.core.initialise_window()
thinking-tower marked this conversation as resolved.
Show resolved Hide resolved
self.canvas = self.core.get_canvas()
self.background_color = background_color
self.key_pressed = set()
Expand Down Expand Up @@ -356,7 +363,8 @@ def arrow_field(self, dir, radius=1, color=0xffffff, bound=0.5, **kwargs):
self.arrows(base, dir, radius=radius, color=color, **kwargs)

def show(self, file=None):
self.core.update()
if self.show_GUI:
self.core.update()
if file:
self.core.screenshot(file)
self.frame += 1
Expand Down
13 changes: 8 additions & 5 deletions taichi/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ class Canvas {
~Canvas() {
}

void set_idendity_transform_matrix() {
void set_identity_transform_matrix() {
thinking-tower marked this conversation as resolved.
Show resolved Hide resolved
transform_matrix = Matrix3(1);
}
};
Expand Down Expand Up @@ -769,10 +769,8 @@ class GUI : public GUIBase {
buffer.initialize(Vector2i(width, height));
canvas = std::make_unique<Canvas>(buffer);
last_frame_time = taichi::Time::get_time();
create_window();
set_title(window_name);
if (!normalized_coord) {
canvas->set_idendity_transform_matrix();
canvas->set_identity_transform_matrix();
}
widget_height = 0;
}
Expand All @@ -785,6 +783,11 @@ class GUI : public GUIBase {

void create_window();

void initialise_window() {
create_window();
set_title(window_name);
}

Canvas &get_canvas() {
return *canvas;
}
Expand All @@ -795,7 +798,7 @@ class GUI : public GUIBase {

void redraw_widgets() {
auto old_transform_matrix = canvas->transform_matrix;
canvas->set_idendity_transform_matrix();
canvas->set_identity_transform_matrix();
for (auto &w : widgets) {
w->set_hover(w->inside(cursor_pos));
w->redraw(*canvas);
Expand Down
1 change: 1 addition & 0 deletions taichi/python/export_visual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void export_visual(py::module &m) {
.def_readwrite("frame_delta_limit", &GUI::frame_delta_limit)
.def_readwrite("should_close", &GUI::should_close)
.def("get_canvas", &GUI::get_canvas, py::return_value_policy::reference)
.def("initialise_window", [](GUI *gui) { gui->initialise_window(); })
.def("set_img",
[&](GUI *gui, std::size_t ptr) {
auto &img = gui->canvas->img;
Expand Down
31 changes: 31 additions & 0 deletions tests/python/test_gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from taichi import make_temp_file
import taichi as ti
import numpy as np
from PIL import Image
import pytest


@ti.host_arch_only
@pytest.mark.parametrize('dtype', [ti.u8, ti.f32])
def test_save_image_without_window(dtype):
n = 255
pixels = ti.field(dtype=dtype, shape=(n, n, 3))

@ti.kernel
def paint(c: dtype):
for i, j, k in pixels:
pixels[i, j, k] = c

gui = ti.GUI("Test", show_GUI=False, res=(n, n))
for i in [0, 32, 64, 128, 255]:
if dtype is ti.u8:
paint(i)
else:
paint(i * 1.0 / n)
gui.set_image(pixels)
image_path = make_temp_file(suffix='.jpg')
yuanming-hu marked this conversation as resolved.
Show resolved Hide resolved
gui.show(image_path)
image = np.array(Image.open(image_path))
thinking-tower marked this conversation as resolved.
Show resolved Hide resolved
delta = (image - i).sum()
assert delta == 0, "Expected image difference to be 0 but got {} instead.".format(
delta)