Сообщение Масштабирование битмапа : GDI+ от 13.01.2017 11:32
Изменено 13.01.2017 12:23 Carc
Масштабирование битмапа : GDI+
Нужно отмасшатбировать битмапку в памяти с заданными зумом. Вчера половину дня промаялся: пищит, мигает, известно куда не попадает.
Все масштабирует, зум на лицо, но обрезает по размеру исходого битмапа. Полный: *опа-кеды.
Уважаемый All, ткните носом, ЧЯДНТ!
Проблема в следующем: все масштабируется, но на выходе получаем обрезанный битмап по размеру исходного. То бишь зум видно невооруженным взглядом — все чики-поки. Но если масштаб больше 100 — тогда обрезается по размеру исходного битмапа. Если масштаб меньше 100 — то опять же, все масштабируется, результирующий битмап ессесна получается меньше исходого. Но опять же все по размеру исходного, просто с черным фоном.
Ни черта не понимаю уже. Что я не так то хоть делаю!?! Уже только что не перепробовал, не попеременял в коде. Ан фиг! Хелп, коллеги!
Все масштабирует, зум на лицо, но обрезает по размеру исходого битмапа. Полный: *опа-кеды.
Уважаемый All, ткните носом, ЧЯДНТ!
HBITMAP CDlgPicResize::DoResizePlus(const LONG cx /*новая ширина для битмпап*/, const LONG cy /*новая высота*/)
{
Gdiplus::Status st;
TRACE(TEXT("DoResizePlus cx=%d cy=%d\n"),cx,cy);
//расcчитываем Zoom-фактор
const float cx_factor=((float)cx/(float)m_szSRC.cx);//(m_szSRC - CSize с исходными размерами 1 в 1)
const float cy_factor=((float)cy/(float)m_szSRC.cy);
TRACE(TEXT("cx_factor=%f, CY_factor=%f\n"),cx_factor,cy_factor);
const HDC hdcFrom=::GetDC(m_hwndRE);//HWND куда потом будет вставлен новый битпа
ASSERT(hdcFrom);
//////////////////////////////////////////////////////////////////////////
//все эти с CAutoGDI*** - это auto-объекты, которые только освобождают ресурсы GDI на выходе
const CAutoGDIHDC_Release release_dc_wnd(hdcFrom,m_hwndRE);
//создаем битмап на котором будем рисовать в памяти
HBITMAP hNew=CreateCompatibleBitmap(hdcFrom,cx,cy);
ASSERT(hNew);
//создаем временный GDI+ битмап и выбираем его в контекст
Gdiplus::Bitmap bmpForDraw(cx
,cy
,PixelFormat24bppRGB) ;
Gdiplus::Graphics g(&bmpForDraw);
g.SetClip(Gdiplus::Rect(0,0,cx,cy)) ;
st = g.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
g.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
//устанавливаем масштабирование
g.ScaleTransform(cx_factor, cy_factor);
{/// рисуем исходный битмап с маштабированием и новой шириной\высотой
Gdiplus::Bitmap bmpTemp(m_hSource,NULL);// m_hSource это HBITMAP исходный
g.DrawImage(&bmpTemp,0,0,cx,cy);
//забираем битмап
HBITMAP h=NULL;
st = bmpForDraw.GetHBITMAP(RGB(255,0,0),&h);
ASSERT(Gdiplus::Ok == st);
ASSERT(h);
ASSERT(h != hNew);
BITMAP bNew={0};
GetObject(h, sizeof(BITMAP),&bNew);
TRACE(TEXT("IN: cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);
hNew=h;
}
#ifdef _DEBUG
//всяко разно дебажные проверки (ширина\высота нового битмапа соответсвуют?
//для просмотра кидаем в файл
BITMAP bNew={0};
GetObject(hNew , sizeof(BITMAP),&bNew);
TRACE(TEXT("new cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);
{
Gdiplus::Bitmap bmpForSave(hNew,NULL);
CLSID bmpClsid ={0};
GetCodecClsid(L"image/bmp", &bmpClsid);
st= bmpForSave.Save(L"C:\\Test_GDI.bmp",&bmpClsid,NULL);
ASSERT(Gdiplus::Ok == st);
}
#endif
return hNew;
}
Проблема в следующем: все масштабируется, но на выходе получаем обрезанный битмап по размеру исходного. То бишь зум видно невооруженным взглядом — все чики-поки. Но если масштаб больше 100 — тогда обрезается по размеру исходного битмапа. Если масштаб меньше 100 — то опять же, все масштабируется, результирующий битмап ессесна получается меньше исходого. Но опять же все по размеру исходного, просто с черным фоном.
Ни черта не понимаю уже. Что я не так то хоть делаю!?! Уже только что не перепробовал, не попеременял в коде. Ан фиг! Хелп, коллеги!
Масштабирование битмапа : GDI+
Нужно отмасшатбировать битмапку в памяти с заданными зумом. Вчера половину дня промаялся: пищит, мигает, известно куда не попадает.
Все масштабирует, зум на лицо, но обрезает по размеру исходого битмапа. Полный: *опа-кеды.
Уважаемый All, ткните носом, ЧЯДНТ!
Проблема в следующем: все масштабируется, но на выходе получаем обрезанный битмап по размеру исходного. То бишь зум видно невооруженным взглядом — все чики-поки. Но если масштаб больше 100 — тогда обрезается по размеру исходного битмапа. Если масштаб меньше 100 — то опять же, все масштабируется, результирующий битмап ессесна получается меньше исходого. Но опять же все по размеру исходного, просто с черным фоном.
Ни черта не понимаю уже. Что я не так то хоть делаю!?! Уже только что не перепробовал, не попеременял в коде. Ан фиг! Хелп, коллеги!
Все масштабирует, зум на лицо, но обрезает по размеру исходого битмапа. Полный: *опа-кеды.
Уважаемый All, ткните носом, ЧЯДНТ!
HBITMAP CDlgPicResize::DoResizePlus(const LONG cx /*новая ширина для битмпап*/, const LONG cy /*новая высота*/)
{
Gdiplus::Status st;
TRACE(TEXT("DoResizePlus cx=%d cy=%d\n"),cx,cy);
//расcчитываем Zoom-фактор
const float cx_factor=((float)cx/(float)m_szSRC.cx);//(m_szSRC - CSize с исходными размерами 1 в 1)
const float cy_factor=((float)cy/(float)m_szSRC.cy);
TRACE(TEXT("cx_factor=%f, CY_factor=%f\n"),cx_factor,cy_factor);
const HDC hdcFrom=::GetDC(m_hwndRE);//HWND куда потом будет вставлен новый битпа
ASSERT(hdcFrom);
//////////////////////////////////////////////////////////////////////////
//все эти с CAutoGDI*** - это auto-объекты, которые только освобождают ресурсы GDI на выходе
const CAutoGDIHDC_Release release_dc_wnd(hdcFrom,m_hwndRE);
//создаем битмап на котором будем рисовать в памяти
HBITMAP hNew=CreateCompatibleBitmap(hdcFrom,cx,cy);
ASSERT(hNew);
//создаем временный GDI+ битмап и выбираем его в контекст
Gdiplus::Bitmap bmpForDraw(cx
,cy
,PixelFormat24bppRGB) ;
Gdiplus::Graphics g(&bmpForDraw);
g.SetClip(Gdiplus::Rect(0,0,cx,cy)) ;
st = g.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
g.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
//устанавливаем масштабирование
g.ScaleTransform(cx_factor, cy_factor);
{/// рисуем исходный битмап с маштабированием и новой шириной\высотой
Gdiplus::Bitmap bmpTemp(m_hSource,NULL);// m_hSource это HBITMAP исходный
g.DrawImage(&bmpTemp,0,0,cx,cy);
//забираем битмап
HBITMAP h=NULL;
st = bmpForDraw.GetHBITMAP(RGB(255,0,0),&h);
ASSERT(Gdiplus::Ok == st);
ASSERT(h);
ASSERT(h != hNew);
BITMAP bNew={0};
GetObject(h, sizeof(BITMAP),&bNew);
TRACE(TEXT("IN: cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);
hNew=h;//ДЛЯ кодо-копателей: да здесь идет потеря вышесозданного HBITMAP, но это издержки тестирования, поскольку уже 100 раз переписывалось и так и эдак,
//изначально все корректно было, и потом, когда доводить буду - “причешу”.
}
#ifdef _DEBUG
//всяко разно дебажные проверки (ширина\высота нового битмапа соответсвуют?
//для просмотра кидаем в файл
BITMAP bNew={0};
GetObject(hNew , sizeof(BITMAP),&bNew);
TRACE(TEXT("new cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);
{
Gdiplus::Bitmap bmpForSave(hNew,NULL);
CLSID bmpClsid ={0};
GetCodecClsid(L"image/bmp", &bmpClsid);
st= bmpForSave.Save(L"C:\\Test_GDI.bmp",&bmpClsid,NULL);
ASSERT(Gdiplus::Ok == st);
}
#endif
return hNew;
}
Проблема в следующем: все масштабируется, но на выходе получаем обрезанный битмап по размеру исходного. То бишь зум видно невооруженным взглядом — все чики-поки. Но если масштаб больше 100 — тогда обрезается по размеру исходного битмапа. Если масштаб меньше 100 — то опять же, все масштабируется, результирующий битмап ессесна получается меньше исходого. Но опять же все по размеру исходного, просто с черным фоном.
Ни черта не понимаю уже. Что я не так то хоть делаю!?! Уже только что не перепробовал, не попеременял в коде. Ан фиг! Хелп, коллеги!