__round_rect(resize_buf, rect, color);
break;
case MV_BARCODE_GENERATE_ATTR_SHAPE_CIRCLE:
- cv::circle(resize_buf,
- cv::Point((x + 2 * sz) * resize_scale + resize_scale / 2,
- (y + 2 * sz) * resize_scale + resize_scale / 2),
+ cv::circle(resize_buf, cv::Point((posx[pos] + 7) * resize_scale, (posy[pos] + 7) * resize_scale),
finder_lenght / 2 * resize_scale, color, -1);
break;
}
}
+static inline float l2_distance(int x1, int y1, int x2, int y2)
+{
+ return std::sqrt(std::pow((x2 - x1), 2) + std::pow((y2 - y1), 2));
+}
+
+static bool is_inside_logo(int x, int y, int org_width, int org_height, mv_barcode_generate_attr_shape_e shape)
+{
+ if (shape == MV_BARCODE_GENERATE_ATTR_SHAPE_CIRCLE) {
+ float distance = l2_distance(x, y, org_width / 2, org_height / 2);
+ return distance < (float) org_width * 0.13f;
+ }
+
+ return (std::abs(x - org_width / 2) < (float) org_width * 0.12f) &&
+ (std::abs(y - org_height / 2) < (float) org_height * 0.12f);
+}
+
/*
* Draw data pattern
* buf already resize x2(by libzint), so finder size is not 7x7, but 14x14.
* Loop also jump 2 pixel each.
*/
static void drawDataPattern(cv::Mat &resize_buf, const cv::Mat &buf, int resize_scale, int org_height, int org_width,
- mv_barcode_generate_attr_shape_e shape)
+ const BarcodeConfig &config)
{
for (int y = 2; y < org_height - 2; y += 2) {
for (int x = 2; x < org_width - 2; x += 2) {
if (is_finder(x, y, org_width, org_height) || buf.at<unsigned char>(y, x, 0) == 255)
continue;
- if (shape == MV_BARCODE_GENERATE_ATTR_SHAPE_RECT)
+ /*
+ * We can find overlap area using opencv Mat inRange, but it's too slow.
+ * So we use simple distance check algorithm.
+ */
+ if (!config.logo_path.empty() && is_inside_logo(x + 1, y + 1, org_height, org_width, config.finder_shape))
+ continue;
+
+ if (config.data_shape == MV_BARCODE_GENERATE_ATTR_SHAPE_RECT)
cv::rectangle(resize_buf,
cv::Rect(x * resize_scale, y * resize_scale, resize_scale * 2, resize_scale * 2),
cv::Scalar(0), -1);
else
/* if radius is same as resize_scale, data look so dense, so -4 */
- cv::circle(resize_buf,
- cv::Point(x * resize_scale + resize_scale / 2, y * resize_scale + resize_scale / 2),
- resize_scale - 4, cv::Scalar(0), -1);
+ cv::circle(resize_buf, cv::Point((x + 1) * resize_scale, (y + 1) * resize_scale), resize_scale - 4,
+ cv::Scalar(0), -1);
}
}
}
+
static void drawDesignQR(cv::Mat &buf, const BarcodeConfig &config)
{
if (config.type != MV_BARCODE_QR || (config.data_shape == MV_BARCODE_GENERATE_ATTR_SHAPE_RECT &&
cv::Mat resize_buf(buf.rows * resize_scale, buf.cols * resize_scale, CV_8UC1, cv::Scalar(255));
drawFinderPattern(resize_buf, resize_scale, buf.rows, buf.cols, config.finder_shape);
- drawDataPattern(resize_buf, buf, resize_scale, buf.rows, buf.cols, config.data_shape);
+ drawDataPattern(resize_buf, buf, resize_scale, buf.rows, buf.cols, config);
cv::cvtColor(resize_buf, buf, cv::COLOR_GRAY2BGR);
}