инициализировать изображение MFC для сплошного цвета

Я не использую c ++ или MFC / ATL и т. Д., Поэтому предположим, что я ничего не знаю.

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

Здесь я хотел бы знать, как я могу инициализировать целевую структуру CImage с белым цветом?

Я сделал это до сих пор (да, я знаю, что у него есть другие стилистические проблемы)

    void ClipBoardFuncs::savePNGASJPEG(char filePath[256], char errorBuff[256]) {
int sizeOfErrorBuff = 256;

CImage imagePNG;
CImage imageJPG;
int xPNG, yPNG = 0;
imagePNG.Load(filePath);

xPNG = imagePNG.GetWidth();
yPNG = imagePNG.GetHeight();

//Create my target JPG same size and bit depth specifiying that there is no alpha channel (dwflag last param)
imageJPG.Create(xPNG, yPNG, imagePNG.GetBPP(), 0);

//Let there be white....
for (int x = 0; x <= xPNG; x++)
{
for (int y = 0; y <= yPNG; y++)
{
imageJPG.SetPixelRGB(x, y, 255, 255, 255);
}
}

//Copy the image over onto on the white
//BitBlt copies everything....
//imagePNG.BitBlt(imageJPG.GetDC(), 0, 0);
//Draw is more like the C# draw examples I've seen
imagePNG.Draw(imageJPG.GetDC(), 0, 0);

imageJPG.ReleaseDC();

HRESULT hr = NULL;
hr = imageJPG.Save(filePath, Gdiplus::ImageFormatJPEG);
imagePNG.Destroy();
imagePNG.ReleaseGDIPlus();

imageJPG.Destroy();
imageJPG.ReleaseGDIPlus();LPCTSTR error = _com_error(hr).ErrorMessage();
strncpy_s(errorBuff, sizeOfErrorBuff, _com_error(hr).ErrorMessage(), _TRUNCATE);

}

Прекрасные люди на C # имеют такой ответ:

Преобразование прозрачного PNG в JPG с не черным цветом фона

Но мне нужно решение C ++ MFC для использования в качестве экспортируемой функции в DLL.

Под экспортированной функцией я подразумеваю ту же архитектуру, что и в kernel32.dll — извините, я не знаю терминологии, чтобы отличать такую ​​библиотеку DLL от библиотеки, заполненной COM-объектами.

Кто-нибудь может предложить более быстрый способ инициализации структуры imageJPEG для сплошного белого цвета, чем вложенные циклы x / y для меня, которые здесь есть?

ура

4GLGuy

2

Решение

Инициализация может быть сделана с Rectangle или же FillRect (за это, FillRect вероятно предпочтительнееRectangle рисует контур прямоугольника в текущем цвете пера, который мы, вероятно, не хотим).

Итак, последовательность выглядит примерно так:

CImage png;
png.Load(pDoc->filename);

CRect rect{ 0, 0, png.GetWidth(), png.GetHeight() };

CImage jpeg;
jpeg.Create(rect.Width(), rect.Height(), png.GetBPP());

auto dc = jpeg.GetDC();
HBRUSH white = CreateSolidBrush(RGB(255, 255, 255));
FillRect(dc, &rect, white);

png.Draw(dc, 0, 0);
jpeg.ReleaseDC();

jpeg.Save(L"Insert File name here", Gdiplus::ImageFormatJPEG);

jpeg.Destroy();
jpeg.ReleaseGDIPlus();
png.ReleaseGDIPlus();

GDI + достаточно «умный», что когда вы делаете .Draw с изображением, имеющим альфа-канал, он учитывает этот канал без необходимости использования TransparentBlt (или что-нибудь подобное).

SetTransparentColor будут не работать на то, что вы пытаетесь сделать здесь. SetTransparentColor для изображения, которое делает не иметь альфа-канал («слой прозрачности»). Затем вы используете его, чтобы выбрать цвет, который будет обрабатываться так, как если бы он был прозрачным — что, безусловно, может быть полезным, но не то, что вам нужно.

Ты можешь использовать memset вместо этого, но только для цветов, где красный, зеленый и синий каналы имеют одинаковые значения (то есть черный, белый или некоторый оттенок серого). В противном случае вы можете выполнить заливку самостоятельно с помощью вложенного цикла, но в большинстве случаев вы, вероятно, захотите использовать FillRect вместо этого (может быть возможно использовать графическое оборудование для ускорения, где цикл будет довольно надежно работать только на процессоре — в худшем случае, они оба примерно одинаковой скорости, но в некоторых случаях FillRect будет быстрее).

1

Другие решения

imagePNG.Draw(imageJPG.GetDC(), 0, 0);

Каждый звонок GetDC должен иметь последующий вызов ReleaseDC, Смотрите также CImage::GetDC документация.

CImage::GetDC обеспечивает дескриптор контекста устройства памяти. Этот дескриптор можно использовать для рисования с использованием стандартных функций GDI. Ручка должна быть позже очищена CImage::ReleaseDC,

CImage::Draw может не знать, что такое прозрачный цвет. Вы должны использовать TransparentBlt сказать ему, что такое прозрачный цвет. Например, чтобы заменить красный цвет на белый:

HDC hdc = imageJPG.GetDC();
CDC dc;
dc.Attach(hdc);
CRect rc(0, 0, xPNG, yPNG);
dc.FillSolidRect(&rc, RGB(255, 255, 255));
dc.Detach();

imagePNG.TransparentBlt(hdc, rc, RGB(255, 0, 0));//replace red with white
imageJPG.ReleaseDC();

...
imageJPG.Save(...);

Или просто использовать CImage::SetTransparentColor:

imagePNG.SetTransparentColor(RGB(255, 0, 0));
imagePNG.Draw(hdc, rc);
for (int x = 0; x <= xPNG; x++){...}

Чтобы сделать это с помощью цикла, измените условие в цикле на x < xPNG а также x < yPNG,

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector