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

Сообщение Re[7]: Масштабирование битмапа : GDI+ от 14.01.2017 11:40

Изменено 14.01.2017 12:01 MTimur

Re[7]: Масштабирование битмапа : GDI+
Здравствуйте, Carc, Вы писали:

C>Дык в том то и дело, что такие варианты с rect или c (x,y,cx,cy) я попробовал сразу. Благо они во всех интернетах мелькают. Но не получается

Он работает, это точно.

C>Дык вроде нету там копирования. Там CStatic и ему делается CStatic::SetBitmap, суть простые обертки над WinAPI.

Ну ок. Не ты копируешь, а CStatic, суть одна.. Размер твоего CStatic cx*cy. Тогда:
1. Размер картинки 0.5(cx*cy). CStatic благополучно отрисовывает ее на своем DC, а все остальное оставляет как есть (черный BG).
2. Размер картинки 2*(cx*cy). CStatic отрисовывает ее на своем DC только то, что помещается в его окно. Результат — обрезан правый и нижний край.
Копируй картинку сам на DC контрола. Я бы прям на диалоге рисовал и обрамлял бы прямоугольником.

C>Код: http://www.amlpages.com/Source/richedit_test.rar, MFC, VS6.

C>Ресайз идет в CDlgResize (это тот диалог, который она запускает при старте, он же и меню Pictures\Resize, но нужно чтобы в CRichEditView был выделен обьект).

Не совсем так как я думал выше, но около того:
void CDlgPicResize::SetPicBitmap(const HBITMAP hBitmap)
{
    ASSERT(hBitmap);
    BITMAP bmp={0};
    GetObject(m_hSource,sizeof(BITMAP),&bmp);

    const HBITMAP hCopy=(HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP, bmp.bmWidth, bmp.bmHeight, LR_CREATEDIBSECTION);
    const HBITMAP hCopy=(HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // fixed!
    ASSERT(hCopy);
    ...


Но теперь при масштабе > 1, черные полосы справа и снизу. Потому что при ресайзе ты устанавливаешь clipping по размеру исходного изображения. Зачем?

Кусок кода рабочего. Просто выпилил все эти g.SetClip.
HBITMAP CDlgPicResize::DoResizePlus(const LONG cx, const LONG cy)
{
...
     Gdiplus::Bitmap bmpForDraw(cx
         ,cy
         ,PixelFormat24bppRGB) ;
    const int sdfsd=bmpForDraw.GetWidth();

    Gdiplus::Graphics* gp=Gdiplus::Graphics::FromImage(&bmpForDraw);
    //Gdiplus::Graphics& g=*gp;
    Gdiplus::Graphics g(hdcComp);
    {/// рисуем исходный битмап с маштабирование и новой шириной\высотой
    Gdiplus::Bitmap bmpTemp(m_hSource,NULL);
    Gdiplus::RectF rDst(0,0,cx,cy);
    Gdiplus::Pen pen(RGB(255,0,0));
    g.DrawRectangle(&pen,rDst);
    g.DrawImage(&bmpTemp,rDst);
    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;
    }
 ...
}


В результате, у меня все заработало. Весь файл после изменений DlgPicResize.cpp

зы А вообще трэш какой-то. Это же не продакшн, да?
Re[7]: Масштабирование битмапа : GDI+
Здравствуйте, Carc, Вы писали:

C>Дык в том то и дело, что такие варианты с rect или c (x,y,cx,cy) я попробовал сразу. Благо они во всех интернетах мелькают. Но не получается

Он работает, это точно.

C>Дык вроде нету там копирования. Там CStatic и ему делается CStatic::SetBitmap, суть простые обертки над WinAPI.

Ну ок. Не ты копируешь, а CStatic, суть одна.. Размер твоего CStatic cx*cy. Тогда:
1. Размер картинки 0.5(cx*cy). CStatic благополучно отрисовывает ее на своем DC, а все остальное оставляет как есть (черный BG).
2. Размер картинки 2*(cx*cy). CStatic отрисовывает ее на своем DC только то, что помещается в его окно. Результат — обрезан правый и нижний край.
Копируй картинку сам на DC контрола. Я бы прям на диалоге рисовал и обрамлял бы прямоугольником.

C>Код: http://www.amlpages.com/Source/richedit_test.rar, MFC, VS6.

C>Ресайз идет в CDlgResize (это тот диалог, который она запускает при старте, он же и меню Pictures\Resize, но нужно чтобы в CRichEditView был выделен обьект).

Не совсем так как я думал выше, но около того:
void CDlgPicResize::SetPicBitmap(const HBITMAP hBitmap)
{
    ASSERT(hBitmap);
    BITMAP bmp={0};
    GetObject(m_hSource,sizeof(BITMAP),&bmp);

    const HBITMAP hCopy=(HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP, bmp.bmWidth, bmp.bmHeight, LR_CREATEDIBSECTION);
    const HBITMAP hCopy=(HBITMAP)CopyImage(hBitmap,IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // fixed!
    ASSERT(hCopy);
    ...


Но теперь при масштабе > 1, черные полосы справа и снизу. Потому что при ресайзе ты устанавливаешь clipping по размеру исходного изображения. Зачем?

Кусок кода рабочего. Просто выпилил все эти g.SetClip.
HBITMAP CDlgPicResize::DoResizePlus(const LONG cx, const LONG cy)
{
...
    HBITMAP hNew=CreateCompatibleBitmap(hdcFrom,2*cx,2*cy); // зачем х2???  
    HBITMAP hNew=CreateCompatibleBitmap(hdcFrom,cx,cy);
...
     Gdiplus::Bitmap bmpForDraw(cx
         ,cy
         ,PixelFormat24bppRGB) ;
    const int sdfsd=bmpForDraw.GetWidth();

    Gdiplus::Graphics* gp=Gdiplus::Graphics::FromImage(&bmpForDraw);
    //Gdiplus::Graphics& g=*gp;
    Gdiplus::Graphics g(hdcComp);
    {/// рисуем исходный битмап с маштабирование и новой шириной\высотой
    Gdiplus::Bitmap bmpTemp(m_hSource,NULL);
    Gdiplus::RectF rDst(0,0,cx,cy);
    Gdiplus::Pen pen(RGB(255,0,0));
    g.DrawRectangle(&pen,rDst);
    g.DrawImage(&bmpTemp,rDst);
    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;
    }
 ...
}


В результате, у меня все заработало. Весь файл после изменений DlgPicResize.cpp

зы А вообще трэш какой-то. Это же не продакшн, да?