簡體   English   中英

"CImg庫可以畫粗線嗎"

[英]can the CImg library draw thick lines

我一直在使用 CImg 庫,並且對集成和使用的簡單程度感到滿意。 然而,我現在想畫粗線(即,超過一個像素的粗細)。 draw_line函數的 API 文檔( 這里)中不清楚如何做到這一點。 該函數的第二個版本(就在文檔中第一個版本的下方)甚至將紋理作為輸入,但同樣沒有寬度。 這么全面的庫居然沒有這個功能,似乎很奇怪。 也許應該使用某種轉換來完成? 我知道我可以使用多邊形來做到這一點(即,一個矩形,我將使用直線的法線計算多邊形的角),但我擔心這會慢得多。

顯然,“開箱即用”是不可能的,但是創建自己的例程,多次調用 CImg 的“draw_line()”例程,一兩個像素移位應該會給你你想要的結果,沒有很多工作。

此函數可用於將粗線繪制為多邊形。

void draw_line(cimg_library::CImg<uint8_t>& image,
    const int x1, const int y1,
    const int x2, const int y2,
    const uint8_t* const color,
    const unsigned int line_width)
{
    if (x1 == x2 && y1 == y2) {
        return;
    }
    // Convert line (p1, p2) to polygon (pa, pb, pc, pd)
    const double x_diff = std::abs(x1 - x2);
    const double y_diff = std::abs(y1 - y2);
    const double w_diff = line_width / 2.0;

    // Triangle between pa and p1: x_adj^2 + y_adj^2 = w_diff^2
    // Triangle between p1 and p2: x_diff^2 + y_diff^2 = length^2 
    // Similar triangles: y_adj / x_diff = x_adj / y_diff = w_diff / length
    // -> y_adj / x_diff = w_diff / sqrt(x_diff^2 + y_diff^2) 
    const int x_adj = y_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));
    const int y_adj = x_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));

    // Points are listed in clockwise order, starting from top-left
    cimg_library::CImg<int> points(4, 2);
    points(0, 0) = x1 - x_adj;
    points(0, 1) = y1 + y_adj;
    points(1, 0) = x1 + x_adj;
    points(1, 1) = y1 - y_adj;
    points(2, 0) = x2 + x_adj;
    points(2, 1) = y2 - y_adj;
    points(3, 0) = x2 - x_adj;
    points(3, 1) = y2 + y_adj;

    image.draw_polygon(points, color);
}

line_width 20 和 3 種顏色的基准。 第一次使用這個函數,第二次使用image.draw_line()繪制一條 1 px 寬的線。

  • 1000,1000 至 2000,2000:216 µs / 123 µs
  • 2000,2000 至 8000,4000:588 µs / 151 µs
  • 3000,1000 至 3020,1000:21 µs / 5 µs

基本上這段代碼與@vll的答案相同,但也處理(x1-x2)/(y1-y2) < 0的情況(我刪除了abs函數)。

void draw_line(cimg_library::CImg<uint8_t>& image,
      const int x1, const int y1,
      const int x2, const int y2,
      const uint8_t* const color,
      const uint8_t line_width,
      const double opacity=1.0)
   {
      if (x1 == x2 && y1 == y2) {
         return;
      }
      // Convert line (p1, p2) to polygon (pa, pb, pc, pd)
      const double x_diff = (x1 - x2);
      const double y_diff = (y1 - y2);
      const double w_diff = line_width / 2.0;

      // Triangle between pa and p1: x_adj^2 + y_adj^2 = w_diff^2
      // Triangle between p1 and p2: x_diff^2 + y_diff^2 = length^2 
      // Similar triangles: y_adj / x_diff = x_adj / y_diff = w_diff / length
      // -> y_adj / x_diff = w_diff / sqrt(x_diff^2 + y_diff^2) 
      const int x_adj = y_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));
      const int y_adj = x_diff * w_diff / std::sqrt(std::pow(x_diff, 2) + std::pow(y_diff, 2));

      // Points are listed in clockwise order, starting from top-left
      cimg_library::CImg<int> points(4, 2);
      points(0, 0) = x1 - x_adj;
      points(0, 1) = y1 + y_adj;
      points(1, 0) = x1 + x_adj;
      points(1, 1) = y1 - y_adj;
      points(2, 0) = x2 + x_adj;
      points(2, 1) = y2 - y_adj;
      points(3, 0) = x2 - x_adj;
      points(3, 1) = y2 + y_adj;

      image.draw_polygon(points, color, opacity);
   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM