Skip to content

Commit d2f309c

Browse files
committed
tex2ocr works.
1 parent da9fdca commit d2f309c

20 files changed

Lines changed: 1415 additions & 90 deletions

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,6 @@ examples/example_sdl_opengl3/example_sdl_opengl3
5050

5151
build/
5252
.cache/
53-
thirdparty/
54-
53+
thirdparty/cef
54+
*.build/
55+
*.dist/

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "examples/example_sdl_opengl2/clip"]
2+
path = examples/example_sdl_opengl2/clip
3+
url = https://github.com/dacap/clip.git

CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STR
44

55
# set c++ standard
66
set(CMAKE_VERBOSE_MAKEFILE ON)
7-
# set(CMAKE_CXX_STANDARD 20)
8-
# set(CMAKE_CXX_STANDARD_REQUIRED ON)
9-
# set(CMAKE_CXX_EXTENSIONS OFF)
7+
set(CMAKE_CXX_STANDARD 20)
8+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
9+
set(CMAKE_CXX_EXTENSIONS OFF)
1010

1111
project(imbrowser)
1212

1313
add_library(imgui STATIC
1414
${CMAKE_CURRENT_LIST_DIR}/imgui.cpp
1515
${CMAKE_CURRENT_LIST_DIR}/imgui_demo.cpp
1616
${CMAKE_CURRENT_LIST_DIR}/imgui_draw.cpp
17-
${CMAKE_CURRENT_LIST_DIR}/imgui_widgets.cpp)
17+
${CMAKE_CURRENT_LIST_DIR}/imgui_widgets.cpp
18+
${CMAKE_CURRENT_LIST_DIR}/whereami.c
19+
${CMAKE_CURRENT_LIST_DIR}/whereami.h)
1820

1921
target_sources(imgui PRIVATE ${CMAKE_CURRENT_LIST_DIR}/imgui_browser.cpp)
2022

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist/
2+
build/

examples/example_sdl_opengl2/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,27 @@ target_link_libraries(${CEF_TARGET} PRIVATE
5555
SDL2::SDL2-static
5656
imgui
5757
OpenGL::GL)
58+
59+
add_custom_command(TARGET ${CEF_TARGET}
60+
PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy
61+
${CMAKE_CURRENT_LIST_DIR}/mathrender.html
62+
$<TARGET_FILE_DIR:${CEF_TARGET}>/mathrender.html)
63+
64+
# Disable clip examples and tests
65+
set(CLIP_EXAMPLES OFF CACHE BOOL "Compile clip examples")
66+
set(CLIP_TESTS OFF CACHE BOOL "Compile clip tests")
67+
set(CLIP_LIB_HEADER_FOLDER ${CMAKE_CURRENT_LIST_DIR}/clip CACHE STRING "Folder where to find clip library headers")
68+
69+
# In case that you have ${PNG_LIBRARY} set to support copy/paste images on Linux
70+
#set(CLIP_X11_PNG_LIBRARY "${PNG_LIBRARY}")
71+
72+
# Add clip subdirectory to compile the library
73+
add_subdirectory(clip)
74+
75+
76+
target_link_libraries(${CEF_TARGET} PRIVATE clip)
77+
target_include_directories(${CEF_TARGET} PRIVATE ${CLIP_LIB_HEADER_FOLDER})
78+
79+
find_package(cppzmq CONFIG REQUIRED)
80+
target_link_libraries(${CEF_TARGET} PRIVATE cppzmq)
81+
target_include_directories(${CEF_TARGET} PRIVATE ${Stb_INCLUDE_DIR})

examples/example_sdl_opengl2/clip

Submodule clip added at 4344f9e
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from transformers import TrOCRProcessor
2+
from optimum.onnxruntime import ORTModelForVision2Seq
3+
from transformers import onnx
4+
5+
model_checkpoint = "breezedeus/pix2text-mfr"
6+
save_directory = "onnx/"
7+
8+
# Load a model from transformers and export it to ONNX
9+
processor = TrOCRProcessor.from_pretrained('breezedeus/pix2text-mfr', force_download=True)
10+
model = ORTModelForVision2Seq.from_pretrained('breezedeus/pix2text-mfr', use_cache=False)
11+
12+
# Save the onnx model and tokenizer
13+
processor.save_pretrained(save_directory)
14+
model.save_pretrained(save_directory)

examples/example_sdl_opengl2/main.cpp

Lines changed: 166 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,69 @@
99
#include "imgui.h"
1010
#include "imgui_impl_sdl.h"
1111
#include "imgui_impl_opengl2.h"
12+
#include <SDL_hints.h>
13+
#include <SDL_video.h>
1214
#include <stdio.h>
1315
#include <SDL.h>
1416
#include <SDL_opengl.h>
1517
#include <cef_app.h>
1618

19+
#include "clip.h"
20+
#include <iostream>
21+
#define STB_IMAGE_WRITE_IMPLEMENTATION
22+
#include "stb_image_write.h"
23+
#include <zmq.hpp>
24+
25+
static ImGuiWindowFlags WindowFlagsNothing()
26+
{
27+
ImGuiWindowFlags window_flags = 0;
28+
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
29+
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings;
30+
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
31+
return window_flags;
32+
}
33+
34+
ImVec2 ImageProportionalSize(const ImVec2& askedSize, const ImVec2& imageSize)
35+
{
36+
ImVec2 r(askedSize);
37+
38+
if ((r.x == 0.f) && (r.y == 0.f))
39+
r = imageSize;
40+
else if (r.y == 0.f)
41+
r.y = imageSize.y / imageSize.x * r.x;
42+
else if (r.x == 0.f)
43+
r.x = imageSize.x / imageSize.y * r.y;
44+
return r;
45+
}
46+
47+
GLuint pic_tex_id = 0;
48+
void impl_StoreTexture(int width, int height, unsigned char* image_data_rgba, int image_type)
49+
{
50+
// it's ok to just delete 0's texture
51+
glDeleteTextures(1, &pic_tex_id);
52+
53+
glGenTextures(1, &pic_tex_id);
54+
glBindTexture(GL_TEXTURE_2D, pic_tex_id);
55+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
56+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
57+
#if defined(HELLOIMGUI_USE_GLES2) || defined(HELLOIMGUI_USE_GLES3)
58+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
59+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
60+
#endif
61+
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
62+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
63+
width,
64+
height, 0, image_type, GL_UNSIGNED_BYTE, image_data_rgba);
65+
}
66+
67+
void png_copy(void *socket_, void *data, int size) {
68+
zmq::message_t request (size);
69+
memcpy(request.data(), data, size);
70+
std::cout << "Sending Image " << std::endl;
71+
zmq::socket_t *socket = (zmq::socket_t *)socket_;
72+
socket->send (request, zmq::send_flags::none);
73+
}
74+
1775
// Main code
1876
int main(int argc, char** argv)
1977
{
@@ -75,10 +133,22 @@ int main(int argc, char** argv)
75133

76134
bool show_in_game_browser_window = true;
77135
// Our state
78-
bool show_demo_window = false;
79-
bool show_another_window = false;
136+
// bool show_demo_window = false;
80137
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
81138

139+
// Prepare our context and socket
140+
zmq::context_t context (1);
141+
zmq::socket_t socket (context, zmq::socket_type::req);
142+
zmq::socket_t control_socket (context, zmq::socket_type::req);
143+
144+
std::cout << "Connecting to hello world server..." << std::endl;
145+
socket.connect ("tcp://localhost:8848");
146+
control_socket.connect ("tcp://localhost:8849");
147+
148+
zmq_pollitem_t items[] = {
149+
{socket, 0, ZMQ_POLLIN, 0},
150+
};
151+
82152
// Main loop
83153
bool done = false;
84154
while (!done)
@@ -95,53 +165,109 @@ int main(int argc, char** argv)
95165
if (event.type == SDL_QUIT)
96166
done = true;
97167
}
168+
zmq_poll(items, IM_ARRAYSIZE(items), 0);
98169

99170
// Start the Dear ImGui frame
100171
ImGui_ImplOpenGL2_NewFrame();
101172
ImGui_ImplSDL2_NewFrame(window);
102173
ImGui::NewFrame();
103174

104-
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
105-
if (show_demo_window)
106-
ImGui::ShowDemoWindow(&show_demo_window);
175+
int windowW, windowH;
176+
SDL_GetWindowSize(window, &windowW, &windowH);
177+
ImGui::SetNextWindowPos(ImVec2(0, 0));
178+
ImGui::SetNextWindowSize(ImVec2(windowW, windowH));
107179

180+
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
181+
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
182+
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
183+
static bool p_open = true;
184+
std::string windowTitle = "Main window (title bar invisible)";
185+
ImGui::Begin(windowTitle.c_str(), &p_open, WindowFlagsNothing());
186+
ImGui::PopStyleVar(3);
108187

109-
if (show_in_game_browser_window)
110-
ImGui::ShowBrowserWindow(&show_in_game_browser_window, ImGui_ImplSDL2_GetCefTexture());
188+
// // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
189+
// if (show_demo_window)
190+
// ImGui::ShowDemoWindow(&show_demo_window);
111191

112-
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
113192
{
114-
static float f = 0.0f;
115-
static int counter = 0;
193+
static std::string value;
194+
static clip::image image;
195+
static bool update_image = false;
196+
static bool wait_reply = false;
197+
if (ImGui::Button("Show clipboard"))
198+
{
199+
if (!clip::get_text(value))
200+
{
201+
value = "Could not get clipboard text";
202+
if (!clip::get_image(image)) {
203+
value = "Could not get clipboard image";
204+
} else {
205+
update_image = true;
206+
wait_reply = true;
207+
auto imageDataSize = image.spec().required_data_size();
208+
auto imageData = image.data();
209+
IM_ASSERT(image.spec().bits_per_pixel / 8 == 4);
210+
for (unsigned int i = 0; i < imageDataSize / 4; i++)
211+
{
212+
std::swap(imageData[i * 4 + 0], imageData[i * 4 + 2]);
213+
}
214+
stbi_write_png_to_func(png_copy, &socket, image.spec().width, image.spec().height, 4, (void *)imageData, image.spec().bytes_per_row);
215+
}
216+
}
217+
}
218+
ImGui::Text("%s", value.c_str());
219+
static ImVec2 imageDispSize;
220+
if (update_image) {
221+
impl_StoreTexture(image.spec().width, image.spec().height, (unsigned char *)image.data(), GL_RGBA);
222+
auto imageSize = ImVec2(image.spec().width, image.spec().height);
223+
imageDispSize = ImageProportionalSize(ImVec2(image.spec().width, image.spec().height), imageSize);
224+
update_image = false;
225+
}
226+
if (wait_reply && items[0].revents & ZMQ_POLLIN) {
227+
zmq::message_t reply;
228+
auto size = socket.recv (reply, zmq::recv_flags::none);
229+
if(size != -1)
230+
{
231+
std::cout << "receive ok." << std::endl;
232+
std::cout << reply.to_string() << std::endl;
233+
ImGui::setTexString(reply.to_string().c_str());
234+
}
235+
wait_reply = false;
236+
}
237+
if (imageDispSize.x != 0)
238+
{
239+
ImGui::Image((void *)(intptr_t)pic_tex_id, imageDispSize);
240+
}
241+
if (ImGui::Button("Set clipboard"))
242+
{
243+
clip::set_text("Hello clipboard!");
244+
}
245+
}
116246

117-
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
247+
ImGui::ShowBrowserWindow(&show_in_game_browser_window, ImGui_ImplSDL2_GetCefTexture());
248+
ImGui::End();
118249

119-
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
120-
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
121-
ImGui::Checkbox("Another Window", &show_another_window);
122-
ImGui::Checkbox("In Game Browser", &show_in_game_browser_window);
250+
// // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
251+
// {
252+
// static float f = 0.0f;
253+
// static int counter = 0;
123254

124-
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
125-
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
255+
// ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
126256

127-
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
128-
counter++;
129-
ImGui::SameLine();
130-
ImGui::Text("counter = %d", counter);
257+
// ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
131258

132-
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
133-
ImGui::End();
134-
}
259+
// ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
260+
// ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
261+
262+
// if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
263+
// counter++;
264+
// ImGui::SameLine();
265+
// ImGui::Text("counter = %d", counter);
266+
267+
// ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
268+
// ImGui::End();
269+
// }
135270

136-
// 3. Show another simple window.
137-
if (show_another_window)
138-
{
139-
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
140-
ImGui::Text("Hello from another window!");
141-
if (ImGui::Button("Close Me"))
142-
show_another_window = false;
143-
ImGui::End();
144-
}
145271

146272
// Rendering
147273
ImGui::Render();
@@ -153,6 +279,10 @@ int main(int argc, char** argv)
153279
SDL_GL_SwapWindow(window);
154280
}
155281

282+
zmq::message_t request (10);
283+
memcpy(request.data(), "quit", 10);
284+
control_socket.send(request);
285+
156286
// Cleanup
157287
ImGui_ImplOpenGL2_Shutdown();
158288
ImGui_ImplSDL2_Shutdown();
@@ -163,5 +293,8 @@ int main(int argc, char** argv)
163293
SDL_Quit();
164294

165295
CefShutdown();
296+
297+
socket.close();
298+
control_socket.close();
166299
return 0;
167300
}

examples/example_sdl_opengl2/mathrender.html

Lines changed: 93 additions & 0 deletions
Large diffs are not rendered by default.

examples/example_sdl_opengl2/temml.min.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)