Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как повернуть изображение в HBITMAP на 180? 
V
    Опции темы
VSergeyV
Дата 14.12.2006, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 299
Регистрация: 9.5.2006
Где: Новосибирск

Репутация: нет
Всего: 3



Как повернуть изображение в HBITMAP на 180?
PM MAIL ICQ   Вверх
Earnest
Дата 14.12.2006, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



1) Считать биты в буфер, поменять местами первую и последнюю строку, вторую и предпоследнюю, etc? закачать обратно в битмап
2) Можно попробовать повернуть на выводе - через соответствующие переметры StretchBlt. 



--------------------
...
PM   Вверх
The Thing
Дата 21.12.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 286
Регистрация: 6.9.2004

Репутация: 1
Всего: 3



Исходник как повернуть изображение на любой угол.. 

файл: TurnImView.h
Код

// TurnImView.h : interface of the CTurnImView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_TURNIMVIEW_H__DDA2FBD8_0C64_4E02_B12D_977665250476__INCLUDED_)
#define AFX_TURNIMVIEW_H__DDA2FBD8_0C64_4E02_B12D_977665250476__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CTurnImView : public CView
{
protected: // create from serialization only
    CTurnImView();
    DECLARE_DYNCREATE(CTurnImView)

// Attributes
public:
    CTurnImDoc* GetDocument();

    float m_iangel;
    bool m_draw;
    
    void Formating(CDC *pDC);
    void LoadFile(CDC *pDC);
    void SinCos(double AngleRad, double &ASin, double &ACos);

// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CTurnImView)
    public:
    virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void DoDataExchange(CDataExchange* pDX);
    //}}AFX_VIRTUAL

// Implementation
public:
    virtual ~CTurnImView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:
    HBITMAP m_hbitmap;
    BITMAP m_bm;
// Generated message map functions
protected:
    //{{AFX_MSG(CTurnImView)
    afx_msg void OnViewSetangle();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in TurnImView.cpp
inline CTurnImDoc* CTurnImView::GetDocument()
   { return (CTurnImDoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TURNIMVIEW_H__DDA2FBD8_0C64_4E02_B12D_977665250476__INCLUDED_)


файл: TurnImView.cpp
Код

// TurnImView.cpp : implementation of the CTurnImView class
//

#include "stdafx.h"
#include "TurnIm.h"

#include "TurnImDoc.h"
#include "TurnImView.h"
#include "math.h"

#include "SetAngle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTurnImView

IMPLEMENT_DYNCREATE(CTurnImView, CView)

BEGIN_MESSAGE_MAP(CTurnImView, CView)
    //{{AFX_MSG_MAP(CTurnImView)
    ON_COMMAND(ID_VIEW_SETANGLE, OnViewSetangle)
    //}}AFX_MSG_MAP
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTurnImView construction/destruction

CTurnImView::CTurnImView()
{
    // TODO: add construction code here
    m_iangel = 0;
    m_draw = false; //ïåðåðèñîâêà
}

CTurnImView::~CTurnImView()
{
}

BOOL CTurnImView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs
    return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CTurnImView drawing

void CTurnImView::OnDraw(CDC* pDC)
{
    CTurnImDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    if(GetDocument()->m_bloadfile){
        LoadFile(pDC);
        GetDocument()->m_bloadfile = false;
    }
    if(m_draw){
        Formating(pDC);
    }
    //pDC->DrawState(CPoint(0,0), CSize(m_bm.bmWidth, m_bm.bmHeight), m_hbitmap, DST_BITMAP);

}

/////////////////////////////////////////////////////////////////////////////
// CTurnImView printing

BOOL CTurnImView::OnPreparePrinting(CPrintInfo* pInfo)
{
    // default preparation
    return DoPreparePrinting(pInfo);
}

void CTurnImView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add extra initialization before printing
}

void CTurnImView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CTurnImView diagnostics

#ifdef _DEBUG
void CTurnImView::AssertValid() const
{
    CView::AssertValid();
}

void CTurnImView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CTurnImDoc* CTurnImView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTurnImDoc)));
    return (CTurnImDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTurnImView message handlers

void CTurnImView::DoDataExchange(CDataExchange* pDX) 
{
    CView::DoDataExchange(pDX);
}

//çàãðóçêà èç êàðòèíêè ôàéëà
void CTurnImView::LoadFile(CDC* pDC)
{
    m_hbitmap = GetDocument()->m_hBitmap; 
    GetObject(m_hbitmap, sizeof(BITMAP), (LPVOID)&m_bm);

    //Ðèñóåì ôàéë
    CDC dc;
    dc.CreateCompatibleDC(pDC);
    dc.SelectObject(m_hbitmap);
    
    //Êîïèðóåì åãî
    ::BitBlt(pDC->m_hDC, 0, 0, m_bm.bmWidth, m_bm.bmHeight, dc.m_hDC, 0, 0, SRCCOPY);
    dc.DeleteDC();
}

void CTurnImView::OnViewSetangle() 
{
    //âûñòàâëÿåì óãîë
    m_draw = true;
    CSetAngle Angle;
    if(Angle.DoModal() == IDOK){
        m_iangel = Angle.GetAngle();
    }
    InvalidateRect(0, 0);
}

// Àëãîðèòì ïîâîðîòà èçîáðàæåíèÿ. Ïóñòü: 
//
// O - ýòî öåíòð ïîâîðîòà, 
// M - íåêàÿ òî÷êà èñõîäíîãî èçîáðàæåíèÿ. 
// Äëÿ êàæäîé òî÷êè M íóæíî íàéòè óãîë alpha ìåæäó îòðåçêîì OM è
// ãîðèçîíòàëüþ è äëèíó r îòðåçêà OM. Òåïåðü, ÷òîáû ïîâåðíóòü èçîáðàæåíèå
// íà óãîë beta, íóæíî êàæäîé òî÷êå M ïðèñâîèòü öâåò òî÷êè èñõîäíîãî
// èçîáðàæåíèÿ ñ êîîðäèíàòàìè x,y, ãäå 
//
// x = xo + r * cos(alpha + beta)
// y = yo + r * sin(alpha + beta)
//
// xo,yo - öåíòð ïîâîðîòà, 
// r - äëèíà îòðåçêà OM 

// Âàæíî èìåííî êàæäîé òî÷êå íîâîãî èçîáðàæåíèÿ ñîïîñòàâëÿòü òî÷êó ñòàðîãî
// èçîáðàæåíèÿ, à íå íàîáîðîò, òàê êàê èíà÷å íåêîòîðûå òî÷êè íîâîãî
// èçîáðàæåíèÿ îñòàíóòñÿ íå çàêðàøåííûìè. 

void CTurnImView::Formating(CDC *pDC){
    CBitmap *bm, *bm1;

    CDC dc, dc1;
    dc.CreateCompatibleDC(pDC);
    dc1.CreateCompatibleDC(pDC);

    int x, y;
    float r;
    int xo, yo;
    double s, c;

    bm = new CBitmap;
    bm->Attach(m_hbitmap);
    dc.SelectObject(bm);

    xo = m_bm.bmWidth/2;
    yo = m_bm.bmHeight/2;
    bm1 = new CBitmap;
    bm1->CreateCompatibleBitmap(pDC, m_bm.bmWidth, m_bm.bmHeight);
    dc1.SelectObject(bm1);
    ::BitBlt(dc1.m_hDC, 0, 0, m_bm.bmWidth, m_bm.bmHeight, dc1.m_hDC, 0, 0, WHITENESS);

    for(y = 0; y < (m_bm.bmHeight - 1); y++){
        for(x = 0; x< (m_bm.bmWidth - 1); x++){
            
            r = sqrt(pow((x - xo), 2) + pow((y - yo), 2));

            SinCos(m_iangel + atan2((y - yo), (x - xo)), s, c);
            dc1.SetPixel(x, y, dc.GetPixel( (int)(xo + r * c), (int)(yo + r * s) ) );
        }
    }
    ::BitBlt(pDC->m_hDC, 0, 0, m_bm.bmWidth, m_bm.bmHeight, dc1.m_hDC, 0, 0, SRCCOPY);
    
    bm1->DeleteObject();
    bm->Detach();
    dc.DeleteDC();
    dc1.DeleteDC();


}

void CTurnImView::SinCos(double AngleRad, double &ASin, double &ACos)
{
    ASin = sin(AngleRad);
    ACos = cos(AngleRad);
}


Файл TurnImDoc.cpp
Код

void CTurnImDoc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        // TODO: add storing code here
    }
    else
    {
        // TODO: add loading code here
        m_strputh = (ar.GetFile())->GetFilePath();
        m_hBitmap = (HBITMAP) LoadImage(0, m_strputh,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
        m_bloadfile = true;

    }
}


Это сообщение отредактировал(а) The Thing - 21.12.2006, 12:02


--------------------
Правильность работы программы зависит от двух велечин.
В нужном месте должны стоять нолик и еденичка.
PM MAIL   Вверх
Earnest
Дата 22.12.2006, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



The Thing, ну ты даешь!
Теоретически, конечно, поворот на 180 - это частный случай поворота на произвольный угол, но за подобное "общее" решение задачи я бы программиста сразу уволила. smile 


--------------------
...
PM   Вверх
The Thing
Дата 22.12.2006, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 286
Регистрация: 6.9.2004

Репутация: 1
Всего: 3



1. ммм.. мы не на работе
2. Я хотел привести более сложный вариант поворота, откуда человек может почерпнуть то, что ему нужно! А на счет работы не переживай.. меня никто не заставит сделать больше, чем это будет оговоренно.. даже поворот на 180 градусов smile
Форум - учебный материал

Добавлено @ 15:46 
А вообще.. (только сейчас заметил...) у него не указана размерность.. по умолчанию идет в радианах! А в радианах - это не прямой угол. И тобою описанный метод - не подходит smile !


--------------------
Правильность работы программы зависит от двух велечин.
В нужном месте должны стоять нолик и еденичка.
PM MAIL   Вверх
Earnest
Дата 25.12.2006, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Точно, скорее всего имелось ввиду - повернуть на 180 радиан... ты прав smile 


--------------------
...
PM   Вверх
The Thing
Дата 25.12.2006, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 286
Регистрация: 6.9.2004

Репутация: 1
Всего: 3



Ну вот.. а меня уже увольнять собрались smile smile 


--------------------
Правильность работы программы зависит от двух велечин.
В нужном месте должны стоять нолик и еденичка.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0967 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.