Информация об изменениях

Сообщение Re: Масштабирование битмапа : GDI+ от 14.01.2017 8:19

Изменено 14.01.2017 8:22 MTimur

Re: Масштабирование битмапа : GDI+
Здравствуйте, Carc, Вы писали:
  Скрытый текст
C>Нужно отмасштабировать битмапку в памяти с заданными зумом. Вчера половину дня промаялся: пищит, мигает, известно куда не попадает.
C>Все масштабирует, зум на лицо, но обрезает по размеру исходого битмапа. Полный: *опа-кеды.
C>Уважаемый All, ткните носом, ЧЯДНТ!

C>
C>HBITMAP CDlgPicResize::DoResizePlus(const LONG cx /*новая ширина для битмпап*/, const LONG cy /*новая высота*/)
C>{
C>    Gdiplus::Status st;

C>    TRACE(TEXT("DoResizePlus cx=%d cy=%d\n"),cx,cy);
    
C>    //расcчитываем Zoom-фактор 
C>    const float cx_factor=((float)cx/(float)m_szSRC.cx);//(m_szSRC - CSize с исходными размерами 1 в 1)
C>    const float cy_factor=((float)cy/(float)m_szSRC.cy);
C>    TRACE(TEXT("cx_factor=%f, CY_factor=%f\n"),cx_factor,cy_factor);

C>    const HDC hdcFrom=::GetDC(m_hwndRE);//HWND куда потом будет вставлен новый битпа
C>    ASSERT(hdcFrom);
C>    //////////////////////////////////////////////////////////////////////////
C>    //все эти с CAutoGDI*** - это auto-объекты, которые только освобождают ресурсы GDI на выходе
C>     const CAutoGDIHDC_Release release_dc_wnd(hdcFrom,m_hwndRE);
C>    //создаем битмап на котором будем рисовать в памяти
C>    HBITMAP hNew=CreateCompatibleBitmap(hdcFrom,cx,cy);
C>    ASSERT(hNew);

C>    //создаем временный GDI+ битмап и выбираем его в контекст
C>    Gdiplus::Bitmap bmpForDraw(cx
C>        ,cy
C>        ,PixelFormat24bppRGB) ;

C>    Gdiplus::Graphics g(&bmpForDraw);
C>    g.SetClip(Gdiplus::Rect(0,0,cx,cy)) ;

C>    st = g.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
C>    g.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
C>    //устанавливаем масштабирование
C>    g.ScaleTransform(cx_factor, cy_factor);
C>    {/// рисуем исходный битмап с маштабированием и новой шириной\высотой
C>    Gdiplus::Bitmap bmpTemp(m_hSource,NULL);// m_hSource это HBITMAP исходный
C>    g.DrawImage(&bmpTemp,0,0,cx,cy);

    
C>    //забираем битмап
C>    HBITMAP h=NULL;
C>    st = bmpForDraw.GetHBITMAP(RGB(255,0,0),&h);
C>    ASSERT(Gdiplus::Ok == st);
C>    ASSERT(h);
C>    ASSERT(h != hNew);
C>    BITMAP bNew={0};
C>    GetObject(h, sizeof(BITMAP),&bNew);
C>    TRACE(TEXT("IN: cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);
C>    hNew=h;//ДЛЯ кодо-копателей: да здесь идет потеря вышесозданного HBITMAP, но это издержки тестирования
C>//, поскольку уже 100 раз переписывалось и так и эдак, 
C>//изначально все корректно было, и потом, когда доводить буду -  “причешу”.
C>    }
    
C>#ifdef _DEBUG
C>    //всяко разно дебажные проверки (ширина\высота нового битмапа соответсвуют?
C>    //для просмотра кидаем в файл
C>    BITMAP bNew={0};
C>    GetObject(hNew , sizeof(BITMAP),&bNew);
C>    TRACE(TEXT("new cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);

C>    {
C>    Gdiplus::Bitmap bmpForSave(hNew,NULL);
C>    CLSID bmpClsid ={0};
    
C>    GetCodecClsid(L"image/bmp", &bmpClsid);
C>    st= bmpForSave.Save(L"C:\\Test_GDI.bmp",&bmpClsid,NULL);
C>    ASSERT(Gdiplus::Ok == st);
C>    }
C>#endif

    
C>    return hNew;
C>}
C>


C>Проблема в следующем: все масштабируется, но на выходе получаем обрезанный битмап по размеру исходного. То бишь зум видно невооруженным взглядом — все чики-поки. Но если масштаб больше 100 — тогда обрезается по размеру исходного битмапа. Если масштаб меньше 100 — то опять же, все масштабируется, результирующий битмап ессесна получается меньше исходого. Но опять же все по размеру исходного, просто с черным фоном.

C>Ни черта не понимаю уже. Что я не так то хоть делаю!?! Уже только что не перепробовал, не попеременял в коде. Ан фиг! Хелп, коллеги!

А если так?
    g.DrawImage(&bmpTemp,0,0);
Re: Масштабирование битмапа : GDI+
Здравствуйте, Carc, Вы писали:
  Скрытый текст
C>Нужно отмасштабировать битмапку в памяти с заданными зумом. Вчера половину дня промаялся: пищит, мигает, известно куда не попадает.
C>Все масштабирует, зум на лицо, но обрезает по размеру исходого битмапа. Полный: *опа-кеды.
C>Уважаемый All, ткните носом, ЧЯДНТ!

C>
C>HBITMAP CDlgPicResize::DoResizePlus(const LONG cx /*новая ширина для битмпап*/, const LONG cy /*новая высота*/)
C>{
C>    Gdiplus::Status st;

C>    TRACE(TEXT("DoResizePlus cx=%d cy=%d\n"),cx,cy);
    
C>    //расcчитываем Zoom-фактор 
C>    const float cx_factor=((float)cx/(float)m_szSRC.cx);//(m_szSRC - CSize с исходными размерами 1 в 1)
C>    const float cy_factor=((float)cy/(float)m_szSRC.cy);
C>    TRACE(TEXT("cx_factor=%f, CY_factor=%f\n"),cx_factor,cy_factor);

C>    const HDC hdcFrom=::GetDC(m_hwndRE);//HWND куда потом будет вставлен новый битпа
C>    ASSERT(hdcFrom);
C>    //////////////////////////////////////////////////////////////////////////
C>    //все эти с CAutoGDI*** - это auto-объекты, которые только освобождают ресурсы GDI на выходе
C>     const CAutoGDIHDC_Release release_dc_wnd(hdcFrom,m_hwndRE);
C>    //создаем битмап на котором будем рисовать в памяти
C>    HBITMAP hNew=CreateCompatibleBitmap(hdcFrom,cx,cy);
C>    ASSERT(hNew);

C>    //создаем временный GDI+ битмап и выбираем его в контекст
C>    Gdiplus::Bitmap bmpForDraw(cx
C>        ,cy
C>        ,PixelFormat24bppRGB) ;

C>    Gdiplus::Graphics g(&bmpForDraw);
C>    g.SetClip(Gdiplus::Rect(0,0,cx,cy)) ;

C>    st = g.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
C>    g.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
C>    //устанавливаем масштабирование
C>    g.ScaleTransform(cx_factor, cy_factor);
C>    {/// рисуем исходный битмап с маштабированием и новой шириной\высотой
C>    Gdiplus::Bitmap bmpTemp(m_hSource,NULL);// m_hSource это HBITMAP исходный
C>    g.DrawImage(&bmpTemp,0,0,cx,cy);

    
C>    //забираем битмап
C>    HBITMAP h=NULL;
C>    st = bmpForDraw.GetHBITMAP(RGB(255,0,0),&h);
C>    ASSERT(Gdiplus::Ok == st);
C>    ASSERT(h);
C>    ASSERT(h != hNew);
C>    BITMAP bNew={0};
C>    GetObject(h, sizeof(BITMAP),&bNew);
C>    TRACE(TEXT("IN: cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);
C>    hNew=h;//ДЛЯ кодо-копателей: да здесь идет потеря вышесозданного HBITMAP, но это издержки тестирования
C>//, поскольку уже 100 раз переписывалось и так и эдак, 
C>//изначально все корректно было, и потом, когда доводить буду -  “причешу”.
C>    }
    
C>#ifdef _DEBUG
C>    //всяко разно дебажные проверки (ширина\высота нового битмапа соответсвуют?
C>    //для просмотра кидаем в файл
C>    BITMAP bNew={0};
C>    GetObject(hNew , sizeof(BITMAP),&bNew);
C>    TRACE(TEXT("new cx=%d cy=%d\n"),bNew.bmWidth,bNew.bmHeight);

C>    {
C>    Gdiplus::Bitmap bmpForSave(hNew,NULL);
C>    CLSID bmpClsid ={0};
    
C>    GetCodecClsid(L"image/bmp", &bmpClsid);
C>    st= bmpForSave.Save(L"C:\\Test_GDI.bmp",&bmpClsid,NULL);
C>    ASSERT(Gdiplus::Ok == st);
C>    }
C>#endif

    
C>    return hNew;
C>}
C>


C>Проблема в следующем: все масштабируется, но на выходе получаем обрезанный битмап по размеру исходного. То бишь зум видно невооруженным взглядом — все чики-поки. Но если масштаб больше 100 — тогда обрезается по размеру исходного битмапа. Если масштаб меньше 100 — то опять же, все масштабируется, результирующий битмап ессесна получается меньше исходого. Но опять же все по размеру исходного, просто с черным фоном.

C>Ни черта не понимаю уже. Что я не так то хоть делаю!?! Уже только что не перепробовал, не попеременял в коде. Ан фиг! Хелп, коллеги!

А если так?
    g.SetClip(Gdiplus::Rect(0,0,cx,cy)) ; // не нужен
    ...
    ...
    g.DrawImage(&bmpTemp,0,0);