Ver código fonte

Fix QR-code/symbol not rendering on top of QR-code correctly

Kristian Vos 5 meses atrás
pai
commit
8b525210bc
3 arquivos alterados com 45 adições e 12 exclusões
  1. 30 11
      src/main.c
  2. 1 1
      src/process_pipeline.c
  3. 14 0
      src/zbar_pipeline.c

+ 30 - 11
src/main.c

@@ -422,6 +422,7 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
         glViewport(
                 offset_x, state.preview_height - size_y - offset_y, size_x, size_y);
 
+        // This rotates the camera preview based on the phone rotation
         if (current_preview_buffer) {
                 glUseProgram(blit_program);
 
@@ -469,20 +470,38 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
                         MPZBarCode *code = &zbar_result->codes[i];
 
                         GLfloat vertices[] = {
-                                code->bounds_x[0], code->bounds_y[0],
-                                code->bounds_x[1], code->bounds_y[1],
-                                code->bounds_x[3], code->bounds_y[3],
-                                code->bounds_x[2], code->bounds_y[2],
+                                code->bounds_x[0], code->bounds_y[0], // Bottom left
+                                code->bounds_x[1], code->bounds_y[1], // Bottom right
+                                code->bounds_x[3], code->bounds_y[3], // Top left
+                                code->bounds_x[2], code->bounds_y[2], // Top right
                         };
 
+                        // Convert the pixel X/Y coordinates to OpenGL coordinates
+                        // (-1 to 1)
                         for (int i = 0; i < 4; ++i) {
-                                vertices[i * 2] =
-                                        2 * vertices[i * 2] /
-                                                state.preview_buffer_width -
-                                        1.0;
-                                vertices[i * 2 + 1] =
-                                        1.0 - 2 * vertices[i * 2 + 1] /
-                                                      state.preview_buffer_height;
+                                // Width/height need to be swapped between portrait
+                                // mode and landscape mode for symbols to render
+                                // correctly
+                                if (state.device_rotation == 0 ||
+                                    state.device_rotation == 180) {
+                                        vertices[i * 2] =
+                                                2 * vertices[i * 2] /
+                                                        state.preview_buffer_width -
+                                                1.0;
+                                        vertices[i * 2 + 1] =
+                                                1.0 -
+                                                2 * vertices[i * 2 + 1] /
+                                                        state.preview_buffer_height;
+                                } else {
+                                        vertices[i * 2] =
+                                                2 * vertices[i * 2] /
+                                                        state.preview_buffer_height -
+                                                1.0;
+                                        vertices[i * 2 + 1] =
+                                                1.0 -
+                                                2 * vertices[i * 2 + 1] /
+                                                        state.preview_buffer_width;
+                                }
                         }
 
                         if (gtk_gl_area_get_use_es(area)) {

+ 1 - 1
src/process_pipeline.c

@@ -1115,7 +1115,7 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
                                                     state_proc.mode->format,
                                                     state_proc.mode->width,
                                                     state_proc.mode->height,
-                                                    state_proc.device_rotation,
+                                                    state_proc.camera_rotation,
                                                     state_proc.mode->mirrored);
         mp_zbar_pipeline_process_image(mp_zbar_image_ref(zbar_image));
 

+ 14 - 0
src/zbar_pipeline.c

@@ -77,6 +77,19 @@ is_3d_code(zbar_symbol_type_t type)
         }
 }
 
+/*
+ * This function gets given the x/y coordinates of the corners of a QR-code/symbol,
+ * but zbar is given an image buffer that may be rotated/mirrored.
+ * So here we adjust the coordinates based on that, so it can be used in src/main.c
+ * to display the symbol on top of the correctly rotated/mirrored camera preview.
+ *
+ * Rotation 0 is the phone in landscape mode (counter-clockwise)
+ * Rotation 90 is the phone in portrait mode upside down
+ * Rotation 180 is the phone in landscape mode (clockwise)
+ * Rotation 270 is the phone in portrait mode
+ *
+ * Mirrored is mainly/only(?) used for front cameras
+ */
 static inline void
 map_coords(int *x, int *y, int width, int height, int rotation, bool mirrored)
 {
@@ -109,6 +122,7 @@ process_symbol(const MPZBarImage *image,
                int height,
                const zbar_symbol_t *symbol)
 {
+        // When device is in portrait mode, swap width/height
         if (image->rotation == 90 || image->rotation == 270) {
                 int tmp = width;
                 width = height;