У меня есть приложение, которое рисует фон из некоторого растрового изображения, используя gdi +. Некоторые из растровых изображений представляют собой вертикальные нелинейные градиенты (например, они имеют ширину 1 пиксель и должны быть растянуты по горизонтали, чтобы заполнить всю ширину элемента управления).
Проблема в том, что с маленькими изображениями (как описано выше) некоторая область управления справа не окрашена.
Я написал тестовую программу, которая масштабирует изображение 1×1 до разных размеров и показывает, что проблема возникает, когда масштабный коэффициент достаточно велик.
void Draw(HDC hDestDC, int destleft, int desttop, int destwidth, int destheight)
{
COLORREF buffer[] = {0xFF0000FF }; // 1 pixel image
const int width = 1, height = 1;
Gdiplus::Bitmap gdipBitmap(width, height, 4*width, PixelFormat32bppARGB, (BYTE*)buffer);
Gdiplus::ImageAttributes attrs;
Gdiplus::Rect dest(destleft, desttop, destwidth, destheight);
Gdiplus::Graphics graphics(hDestDC);
graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor);
graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf);
graphics.DrawImage(&gdipBitmap, dest, 0, 0, width, height, Gdiplus::UnitPixel, &attrs);
}
// OnPaint:
for(int i=0; i<800; ++i)
Draw(hdc, 0, i, i, 1); // scale 1x1 image to different width
Я бы использовал этот тест, чтобы нарисовать гладкий «треугольник», но вместо этого линии не имеют размера именно так как указано целевым прямоугольником:
http://i.imgur.com/NNpMvmW.png
Есть ли способ исправить это поведение? Мне нужно вывести растровое изображение с точно таким же размером, как указано (учитывая альфа-канал исходного изображения и без интерполяции с фоном по краям).
П.С .: Я должен использовать GDI +, потому что в реальном коде используются некоторые ImageAttributes, предоставляемые gdiplus.
Итак, я просто закончил пробовать все возможные значения для разных вариантов и наконец нашел подходящие для меня.
SetSmoothingMode
(как предложено Na Na) не оказало никакого визуального влияния на изображение.
тем не мение SetInterpolationMode(InterpolationModeBilinear)
(или лучше) производит точный размер изображения, но также интерполирует края изображения с фоном. Результат выглядит как этот, что не соответствует моим требованиям.
Наконец, настройка ImageAttibute
«s WrapMode
Вариант делает свое дело:
attrs.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
Результат именно то, что я хотел: http://i.imgur.com/rYKwAmZ.png
С помощью InterpolationModeNearestNeighbor
а также дефолт WrapMode
приводит к неточному размеру отрендеренного изображения. Чтобы избежать этого, установите WrapModeTileFlipXY
=> Другие варианты (например, InterpolationMode
) может иметь любое желаемое значение без влияния на размер визуализируемого изображения.
Ты пытался этот?
Может помочь метод сглаживания сглаживания.