2016-09-15 2 views
0

При использовании Cairo 1.14.6 для отображения я обнаружил, что переписывание того же пути другим цветом не обязательно перезаписывает все пиксели и оставляет нежелательные артефакты.Невозможность перезаписать сглаженные пиксели в Каире

В качестве доказательства моей претензии я предлагаю этот вывод из краткого автономного примера, источник которого следует далее ниже.

enter image description here

Объяснение шести частей изображения, слева направо:

  1. Оригинальная форма погладил синим цветом.
  2. Оригинальная форма, переписанная в RGBA белом.
  3. Оригинальная форма, переписанная в RGB-белом.
  4. Оригинальная форма, переписанная в RGBA-белизне с режимом CAIRO_OPERATOR_SOURCE.
  5. Оригинальная форма, перезаписанная в RGBA-белом режиме CAIRO_OPERATOR_SOURCE и CAIRO_ANTIALIAS_NONE.
  6. Оригинальная форма, переписанная в RGBA-белизне, с режимом CAIRO_OPERATOR_SOURCE и CAIRO_ANTIALIAS_BEST.

Изображение генерировали из следующего кода:

#include "cairo/cairo.h" 

#define M_PI 3.14159265358979323846 

void draw_shape(cairo_t* cr, int x, int y) { 
    cairo_arc(cr, 50 + x, 50 + y, 48, -M_PI, -M_PI/2); 
    cairo_stroke(cr); 
    cairo_move_to(cr, x + 2, y + 2); 
    cairo_line_to(cr, x + 48, y + 48); 
    cairo_stroke(cr); 
} 

int main(int argc, char** argv) { 
    int x = 0; 
    int y = 0; 
    cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 300, 50); 
    cairo_t* cr = cairo_create(surface); 

    /* Draw a white background and a few shapes to overwrite */ 
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); 
    cairo_paint(cr); 
    cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 1.0); 
    draw_shape(cr, x, y); x += 50; 
    draw_shape(cr, x, y); x += 50; 
    draw_shape(cr, x, y); x += 50; 
    draw_shape(cr, x, y); x += 50; 
    draw_shape(cr, x, y); x += 50; 
    draw_shape(cr, x, y); x += 50; 
    x = 50; 

    /* Leftmost shape is left unchanged for reference */ 

    /* Stroke in RGBA opaque white */ 
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); 
    draw_shape(cr, x, y); x += 50; 

    /* Stroke in RGB white */ 
    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); 
    draw_shape(cr, x + 0, y); x += 50; 

    /* Stroke in opaque white without blending */ 
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); 
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 
    draw_shape(cr, x, y); x += 50; 

    /* Stroke in opaque white without blending, with no antialiasing */ 
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); 
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); 
    draw_shape(cr, x, y); x += 50; 

    /* Stroke in opaque white without blending, with best antialiasing */ 
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); 
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); 
    draw_shape(cr, x, y); x += 50; 

    /* Write the results to a file */ 
    cairo_surface_write_to_png(surface, "output.png"); 

    return 0; 
} 

Это не делает интуитивное чувство для меня, что перезапись ту же самую форму, не будет перезаписывать все его пикселей, особенно если я заставляю его в не смешивающийся режим CAIRO_OPERATOR_SOURCE. Результаты одинаковы на фреймбуфере, который составляет мою фактическую поверхность, поэтому это не проблема с бэкэнд.

Каир обычно так хорош в своих действиях, что я очень этому удивляюсь. Нет ли способа переписать сглаженную форму точно в Каире?

ответ

0

То, что я пытаюсь сделать, по-видимому, невозможно. Я отправил мой question в список рассылки Каира и предложил два варианта:

  1. Храните копии исходных пикселей перед нанесением на них:. «Сглаживание включает смешивание Если вы не хотите, антиалиасинга, выключи." (Link)
  2. Нарисуйте гораздо более высокое разрешение: «Единственное реальное решение - сделать гораздо более высокое разрешение с охватом, округленным до нуля или по одному для каждого пикселя». (Link)

Более конкретно:

Все, что хранится в пикселе от первого рисунка является то, что был покрыт формой процента пикселя. Он не помнит точно, какие части пикселя покрыты.

Поскольку сглаживание обязательно связано с смешиванием, и поскольку Каир не помнит, какая часть субпикселя привела к смешиванию, у него нет способа узнать, как отменить это смешение.

Смежные вопросы