сжать картинку
От: Аноним  
Дата: 07.02.05 11:58
Оценка:
Так, вопрос:

есть jpg file, картинка, которую надо показать на диалоге. Есть всевозможные классы, которые помогают в этом, но все они показывают картинки в оригинальном размере.
Как я могу изменить размер картинки? Например, картинка 50х50, а мне надо изобразить её на диалоге 20х20, т.е. сжать её. Всё это динамично, т.е. картинки могут быть разные, их нужно менять во время исполнения программы. Их нужно только показать на диалоге. Может, есть у кого-то код функции по сжатию jpg file?

Заранее благодарна за помощь.
Re: сжать картинку
От: Аноним  
Дата: 07.02.05 13:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Так, вопрос:


А>есть jpg file, картинка, которую надо показать на диалоге. Есть всевозможные классы, которые помогают в этом, но все они показывают картинки в оригинальном размере.

А>Как я могу изменить размер картинки? Например, картинка 50х50, а мне надо изобразить её на диалоге 20х20, т.е. сжать её. Всё это динамично, т.е. картинки могут быть разные, их нужно менять во время исполнения программы. Их нужно только показать на диалоге. Может, есть у кого-то код функции по сжатию jpg file?

А>Заранее благодарна за помощь.


посмотри классик CxImage
Re: сжать картинку
От: algol Россия about:blank
Дата: 07.02.05 13:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>есть jpg file, картинка, которую надо показать на диалоге. Есть всевозможные классы, которые помогают в этом, но все они показывают картинки в оригинальном размере.

А>Как я могу изменить размер картинки? Например, картинка 50х50, а мне надо изобразить её на диалоге 20х20, т.е. сжать её. Всё это динамично, т.е. картинки могут быть разные, их нужно менять во время исполнения программы. Их нужно только показать на диалоге. Может, есть у кого-то код функции по сжатию jpg file?

Все это можно сделать без всяких классов, с помощью только IPicture, OleLoadPicturePath() и какой-то там Render():
BOOL CMyDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO: Add extra initialization here
    HRESULT hr;
    hr = ::OleLoadPicturePath(L"C:\\test.jpg", NULL, 0, 0, IID_IPicture, (void**)&m_pPicture);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

HRESULT CMyDlg::DrawJpg(CDC& hdc, CComPtr<IPicture>& m_pPicture, int CtrlId)
{
    if (m_pPicture)
    {
        // Get the width and the height of the picture
        long hmWidth = 0, hmHeight = 0;
        m_pPicture->get_Width(&hmWidth);
        m_pPicture->get_Height(&hmHeight);

        // Convert himetric to pixels
        int nWidth    = MulDiv(hmWidth, ::GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
        int nHeight    = MulDiv(hmHeight, ::GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);

        CRect rcBounds;
        GetDlgItem(CtrlId)->GetWindowRect(&rcBounds);
        ScreenToClient(&rcBounds);

        // Display the picture using IPicture::Render
        return m_pPicture->Render(
            hdc,                            // [in] Handle of device context on which to render the image
            rcBounds.left,                    // [in] Horizontal position of image in hdc
            rcBounds.top,                    // [in] Vertical position of image in hdc
            rcBounds.right - rcBounds.left,    // [in] Horizontal dimension of destination rectangle
            rcBounds.bottom - rcBounds.top, // [in] Vertical dimension of destination rectangle
            0,                                // [in] Horizontal offset in source picture
            hmHeight,                        // [in] Vertical offset in source picture
            hmWidth,                        // [in] Amount to copy horizontally in source picture
            -hmHeight,                        // [in] Amount to copy vertically in source picture
            &rcBounds                        // [in, optional] Pointer to position of destination for a metafile hdc
            );
    }
    return S_OK;
}

void CMyDlg::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    CDialog::OnPaint();
    DrawJpg(dc, m_pPicture, IDC_PICTURE1);
}

где IDC_PICTURE1 — контрол, на месте которого будет отрисована картинка, а m_pPicture — CComPtr<IPicture> (нужно подключить <atlbase.h>).
Re[2]: менять картинки на диалоге
От: olga sayenko  
Дата: 07.02.05 16:04
Оценка:
Здравствуйте, algol, Вы писали:

A>Все это можно сделать без всяких классов, с помощью только IPicture, OleLoadPicturePath() и какой-то там Render():


Это я была

Всё это работает. Спасибо
Но есть другая проблема Диалог создается без картинки, нажимается кнопка ОК, и появляется картинка. Нажимаем опять ОК, и появляется другая картинка. И так далее... Например, 10 картинок...

Как перерисовать диалог?

Уффффф, уже много чего пробовала, не перерисовывается диалог Если DrawJpg() вызывать не из OnPaint(), ничего не работает. Может как-то только область картинки перерисовывать...
Re[3]: менять картинки на диалоге
От: algol Россия about:blank
Дата: 07.02.05 16:57
Оценка:
Здравствуйте, olga sayenko, Вы писали:

OS>Но есть другая проблема Диалог создается без картинки, нажимается кнопка ОК, и появляется картинка. Нажимаем опять ОК, и появляется другая картинка. И так далее... Например, 10 картинок...


OS>Как перерисовать диалог?


OS>Уффффф, уже много чего пробовала, не перерисовывается диалог Если DrawJpg() вызывать не из OnPaint(), ничего не работает. Может как-то только область картинки перерисовывать...


CWnd::RedrawWindow() или Invalidate() и UpdateWindow(). Чтобы не перерисовывать весь диалог, вызов DrawJpg лучше поместить в обработчик WM_PAINT контрола, а не всего диалога, и вызывать перерисовку контрола.
Re: сжать картинку
От: olga sayenko  
Дата: 08.02.05 10:14
Оценка:
Благодарна всем за помощь

Я нашла класс CPicture в codeproject.com. Всё работает.
Чтобы менять картинки на диалоге при нажатии кнопки, я сделала следующее:

1. Добавляем объект CRect, чтобы задавать размеры картинки, и объект CPicture.

#include "Picture.h" 

/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

class CMyDlg : public CDialog
{
// Construction
public:
  CMyDlg(CWnd* pParent = NULL);    // standard constructor
  CPicture  m_Picture;
  CRect     m_rectPicSize;

......



2. Дальше переписуем OnPaint.

void CMyDlg::OnPaint() 
{
  CPaintDC dc(this); // device context for painting
  
  CDialog::OnPaint();
  
  m_Picture.Show(&dc, m_rectPicSize); // show picture
}


3. Дальше пишем функцию кнопки. Например, OnOK. Задаем верхнию левую позицию и желаемые размеры картинки: или постоянные, или относительно оригинальных размеров.

void CMyDlg::OnOK() 
{
  m_Picture.Load("image.jpg"); // or full picture path
  
  m_rectPicSize.left    = 30;
  m_rectPicSize.top     = 30;
  m_rectPicSize.right   = m_Picture.m_Width / 2; // diminish original Width 
  m_rectPicSize.bottom  = m_Picture.m_Height / 2; // diminish original Height 

  CWnd::RedrawWindow();
}


4. Можно убрать картинку. Например, при нажатии другой кнопки.

void CMyDlg::OnButton2() 
{
  m_Picture.FreePictureData();
  CWnd::RedrawWindow();
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.