Здравствуйте! Мне нужно загрузить из файла/ресурса png рисунок с альфа пикселями и вывести его на контекст. С загрузкой хорошо справляется GDI+, но вот с выводом изображения Graphics::DrawImage() всё плохо, поэтому я решил использовать GDI (StretchBlt и т.д.). Но в StretchBlt Bitmap не запихнёшь, нужен HBITMAP. У Bitmap есть метод GetHBITMAP(Color, HBITMAP*), и в нём-то и проблема: он, почему-то конвертирует с потерей прозрачности. Я пробовал передавать Color::Black и Color::Transparent, но ничего не помогает. Как тогда получить HBITMAP с прозрачностью?
ОБНОВЛЕНО
Я понял в чём была ошибка и она глупая. Ниже вы можете увидить мой код, звёздочками я выделил то чего не было. То есть я рисовал изображение на второй буффер, на котором ничего не было, и удивлялся почему-это, альфа пиксели чёрные. Теперь я додумался что нужно сначала нарисовать на буфер фон, а потом уже рисовать изображение. Но опять проблема: Рисую несколько картинок, вместо картинки 1920/1080(мой экран) просто чёрное(у картинки нет альфа пикселей), картинки других размеров, 100/100 например, в произвольных расположениях рисуются, но с чёрным прямоугольником в левом верхнем углу(у картинки нет альфа пикселей). Если закрасить главный фон(перед выводом изображения 1920/1080, то фон таким же и будет(картинка вообще никак не выводится, получается?), у маленьких картинок цвет прямоугольника такой же становится(походу это прозрачность(но альфа пикселей,ещё раз, там нет).
Я так понимаю, второй раз использовать SelectObject нельзя, да? В общем, подскажите в чём тут проблема?
class Imagee
{
HDC hdc; HBITMAP bm;
Imagee(HDC hdc, HBITMAP bm, another args)
{
this->hdc=CreateCompatibleDC(hdc);
this->bm=bm;
SelectObject(this->hdc,this->bm);
}
void draw(int hdcc, int x,int y, int cx, int cy)
{
**StretchBlt(this->hdc,0,0,cx,cy,hdcc,x,y,cx,cy,SRCCOPY);
SelectObject(this->hdc,this->bm); **
StretchBlt(this->hdcc,x,y,cx,cy,hdc,0,0,cx,cy,SRCCOPY);
};
};
Imagee *image;
void render()
{
for(;;)
{
//здесь я загружая через гди+ битмам, конвертирую его в хбитмап, записывая в перменную HBITMAP hbm
if(image==0)
image=new Imagee(hdc_mem, hbm, x, y и т.д.);
image->draw(hdc_mem, x, y и т.д.);
StretchBlt(hdc_main,0,0,1920,1080,hdc_mem,0,0,1920,1080,SRCCOPY); //hdc_main главный дс, hdc_mem буфер
}
}
Ответ
Отвечая на вопрос:
_Check_return_ ::HBITMAP
LoadPng(_In_z_ const ::LPWSTR psz_file_path)
{
::HBITMAP bitmap_handle{};
if(psz_file_path)
{
const ::BOOL embedded_color_management{TRUE};
::Gdiplus::Bitmap bitmap{psz_file_path, embedded_color_management};
if(::Gdiplus::Status::Ok == bitmap.GetLastStatus())
{
const ::Gdiplus::Color background{0, 0, 0, 0};
if(::Gdiplus::Status::Ok != bitmap.GetHBITMAP(background, &bitmap_handle))
{
bitmap_handle = NULL;
}
}
}
return(bitmap_handle);
}
Как ни странно, но Color::Transparent это не то же самое, что 0, 0, 0, 0. Еще стоит отметить что полученная картинка будет уже с предварительно умноженным (premultiplied) альфа каналом, т.е. пригодная для рисования посредством GdiAlphaBlend и прочих функций.
Комментариев нет:
Отправить комментарий