Draw overlay

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 23 Jan 2013, 18:00

mesajflaviu wrote:Nu am folosit CImageView din exemplul lui Ovidiu, nu pentru ca n-ar fi fost mai elegant, dar pentru o aplicatie test e mai simplu sa implementez offline drawing direct in CMyView.
[...]
Serios, pe bune? :)
O fi, insa ar trebui sa-ti dea de gandit ca nu-i OK ce-ai facut din moment ce ai ajuns iarasi la beleaua initiala cu numele "aceasta oscilatie". ;)
In fine, o sa incerc sa ma uit mai cu atentie, imediat ce gasesc un pic de timp.



mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 23 Jan 2013, 21:52

O sa incerc sa fac un proiect de test cu CImageView, insa oscilatia nu e la overlay (text-ul acela fix), ci la obiectele fixe pe bitmap (dreptunghiuri, linii, elipse, etc). O sa pun cat de repede un proiect de test refacut ...

mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 24 Jan 2013, 11:22

Am introdus clasa CImageView in TestDraw10, si desi e desalata imaginea (bitmap-ul) fata de obiectele fixe, se pare ca nu mai am acea oscilatie ... si nu inteleg de ce ... trebuie sa mai sap ....

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 25 Jan 2013, 16:19

Cum adica "e desalata imaginea " ?

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 27 Jan 2013, 13:27

Vad ca tot nu vrei sa-mi spui ce-i aia "imagine desalata"... :)
In fine, cred ca daca vrei sa "editezi" bitmapul sursa adaugand peste el diverse chestii, cel mai usor si mai lipsit de dureri de cap e sa folosesti un DC intermediar, pentru desenare. Asta pe deopearte ca sa eviti mazgalirea direct in bitmapul sursa, ceea ce ar duce la problem intre doua desenari, pe de alta parte ca sa pastram calea aleasa, fara sa ne enervam cu viewport-uri, DPtoLP-uri, LPtoDP-uri si alte minuni de genul asta, pe care ti-am spus de la inceput sa le dai la boala. ;)

Vezi proiectul demo atasat, care deseneaza un dreptunghi cu text in mijocul imaginii.
Image_scroll_zoom_demo (2).zip
(49.19 KiB) Downloaded 197 times
Modificarile fata de demo-ul precedent le-am notat cu // NEW.
Daca ceva nu-I destul de clar sau nu-I OK, te rog sa-mi spui.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 27 Jan 2013, 14:09

Cateva observatii suplimentare:

1. Sunt sigur ca o sa-mi spui ca, pentru ca am desenat peste bitmap-ul initial la scara 1:1, la zoom-uri bengoase o sa apara cu blur. Asta e, atat poate StretchBlt, atat face. Poate ca, schimband mapping mode ar salva un pic situatia, cel putin la text, insa ar iesi ceva gen "salba de margaritare intr-o albie de porci". :)
Asa ca revin la ce-am spus la inceput: utilizeaza GDI+, care fata de GDI-ul clasic stie metode de interpolare care iti permit sa obtii imagini de calitate mult mai buna atunci cand faci resize la imagini.

2. Cand ai pornit accest topic, am inteles ca vrei sa faci doar un image viewer. Acum se pare ca vrei sa-l faci si image editor, nu-i asa? Deci te rog sa nu ma critici pentru ca am desenat pe bitmap oarecum "hardcoded". Asta a fost doar pentru demo si ca un fast fix. Pana la un editor cat de cat serios mai e mult de lucru...

mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 28 Jan 2013, 10:15

De vineri de la amiaza n-am mai apucat la PC, si pana atunci n-am mai putut lucra la aplicatia de test TestDraw10 ... in incercarea mea de a pune obiecte fixe peste bitmap, la zoom, imaginea ramanea in stanga iar obiectele o "luau" in dreapta, de aia i-am zis "imagine desalata", dar n-am pus "opera de arta" pe forum ...

Acum am vazut aplicatia de test "Image_scroll_zoom_demo (2).zip", o incerc acum si revin ...

mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 28 Jan 2013, 10:58

Am incercat proiectul, insa mi se pare ca merge greu, parca nu ar lucra double-buffering ... am incercat cu poze maricele, poze care se misca foarte bine cu versiunea precedenta de image_scroll_zoom_demo ... singurul lucru care l-am facut este sa sterg din proiect Rectangle.cpp si Shape .cpp sa pot compila proiectul ... ma uit sa vad care e problema, si revin iarasi ...
Attachments
Image_scroll_zoom_demo (2).zip
(61.86 KiB) Downloaded 196 times

mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 28 Jan 2013, 14:27

De ce imi era frica n-am scapat: in proiectul real desenarea se face cu CDib. Am mai incercat eu sa introduc de-a lungul acestui post CDib in proiectele de test, solutia finala n-are CDib. Acuma, cand am incercat sa aplic double-buffering la proiectul original, am dat de prag ... poate e simplu, dar eu n-am reusit.

CDib are metoda Draw:

Code: Select all

BOOL CDib::Draw(CDC* pDC, CPoint pointDest, CSize sizeDest, CPoint pointSource, CSize sizeSource)
{
	// ...
	StretchDIBits(hdc, pointDest.x, pointDest.y, sizeDest.cx, sizeDest.cy,
		pointSource.x, pointSource.y, sizeSource.cx, sizeSource.cy,
		m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);
}
bun.
Implementarea in CMyView::OnDraw este simpla:

Code: Select all

void CMyView::OnDraw(CDC* pDC)
{
	CRect rectClient;
	GetClientRect(&rectClient);
	CBitmapMDIDoc* pDoc = GetDocument();

	CPoint ptPrevViewportOrg = pDC->SetViewportOrg(CPoint(0, 0));
	CMemDC DrawDC(pDC, rectClient.right, rectClient.bottom);
	if(NULL == m_brush.GetSafeHandle())
		m_brush.CreateHatchBrush(HS_DIAGCROSS, m_sBackgroundStyle.crHatch);
	DrawDC.SelectObject(&m_brush);
	DrawDC.PatBlt(0, 0, rectClient.right, rectClient.bottom, PATCOPY);
	DrawImage(&DrawDC, pDC);
	pDC->BitBlt(0, 0, rectClient.Width(), rectClient.Height(), &DrawDC, 0, 0, SRCCOPY);
	pDC->SetViewportOrg(ptPrevViewportOrg);
}
simplu.
Problema e in DrawImage: daca am facut in modul urmator:

Code: Select all

void CMyView::DrawImage(CDC* pDestinationDC, CDC* pDC)
{
	ASSERT_VALID(pDestinationDC);
	CMyDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// ....
	pDoc->m_dibDisplay->Draw(pDestinationDC, CPoint(xDst, yDst), CSize(nDstWidth, nDstHeight), 
		CPoint(xSrc, ySrc), CSize(nSrcWidth, nSrcHeight));
}
am un bitmap cat zona client, niciodata mai mare, e logic sa fie asa, fiindca pDestinationDC are masurile zonei client. Am incercat sa selectez tot bitmap-ul din CDib in modul urmator:

Code: Select all

void CMyView::DrawImage(CDC* pDestinationDC, CDC* pDC)
{
	ASSERT_VALID(pDestinationDC);
	CMyDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CBitmap Bitmap;
	Bitmap.FromHandle(pDoc->m_dibDisplay->m_hBitmap);
	CMemDC SourceDC(pDC, &Bitmap);
	pDestinationDC->StretchBlt(xDst, yDst, nDstWidth, nDstHeight, &SourceDC, 
		xSrc, ySrc, nSrcWidth, nSrcHeight, SRCCOPY);
}
nu merge nici asa, fiindca rezultatul "Bitmap.FromHandle(pDoc->m_dibDisplay->m_hBitmap);" este intotdeauna 0 (NULL) ... am pe view numai fundalul, fara bitmap ... poate e simplu, dar cum pun in pDestinationDC bitmap-ul din CDib ? Sau cum desenez cu CDib::OnDraw(...) direct in pDestinationDC ?

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 28 Jan 2013, 15:23

mesajflaviu wrote:Am incercat proiectul, insa mi se pare ca merge greu, parca nu ar lucra double-buffering ... am incercat cu poze maricele, poze care se misca foarte bine cu versiunea precedenta de image_scroll_zoom_demo ... singurul lucru care l-am facut este sa sterg din proiect Rectangle.cpp si Shape .cpp sa pot compila proiectul ... ma uit sa vad care e problema, si revin iarasi ...
Da sigur merge mai greu pentru ca face o copie la bitmapul sursa in DC-ul intermediar (cel pentru desenat shape-uri peste imaginea initiala) la fiecare afisare pe ecran. Am facut asa doar pentru simplitatea demonstratiei. Poti optimiza, mergand pe acelasi principiu, facand copia respectiva numai cand adaugi un shape. Ti-am spus ca mai e de lucru pana sa iasa un "editor".

PS. Poti, te rog, s-o lasi mai moale cu CDib-ul ala? Ti-am spus ca ma calca pe bataturi... :)

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 28 Jan 2013, 16:42

Am uitat sa spun.
Asazisul "double-buffering" nu inseamna neaparat crestere de viteza.
Inseamna ca se deseneaza mai intai intr-un buffer intermediar, in memorie, intr-un memory device context, zii cum vrei, si abia cand s-a termiat tot de desenat, se transfera imaginea rezultata pe ecran.
Asta elimina flicareala si alte efecte suparatoare.

mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 28 Jan 2013, 17:06

Ovidiu Cucu wrote:Am uitat sa spun.
Asazisul "double-buffering" nu inseamna neaparat crestere de viteza.
Inseamna ca se deseneaza mai intai intr-un buffer intermediar, in memorie, intr-un memory device context, zii cum vrei, si abia cand s-a termiat tot de desenat, se transfera imaginea rezultata pe ecran.
Asta elimina flicareala si alte efecte suparatoare.
Asa e, dar fiindca in memory device context ai pus bitmap-ul cat zona de client, si nu mai mult, asa cum am incercat eu, asta i-a dat un plus insemnat de performanta. (De fapt, acest detaliu face diferenta).

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 29 Jan 2013, 18:13

Pai am spus si eu mai sus care-i buba. No problem, se poate repara. Numai sa gasesc putin timp, poate maine...

mesajflaviu
Membru++
Membru++
Posts: 688
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Draw overlay

Post by mesajflaviu » 30 Jan 2013, 10:56

Asta ar fi un exercitiu bun pentru mine ... nu stiu daca reusesc sa rezolv, dar de incercat, incerc.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Draw overlay

Post by Ovidiu Cucu » 30 Jan 2013, 16:05

Pai nu-i greu. Folosisem un DC intermediar pentru a compune imaginea initala cu alte chestii si in care copiam tot bitmapul sursa la fiecare afisare.
Din cauza aceea merge greu pentru bitmapuri babane. Ca sa imbunatatim asta, nu-l mai copiem la fiecare afisare (pe OnDraw) ca nu-I nevoie, ci doar atunci cand se schimba ceva (ex. s-a mai desenat ceva nou peste).
Ia arunca un ochi in exemplu si spune acum cum merje...
Image_scroll_zoom_demo (3).zip
(53 KiB) Downloaded 233 times
Da clice la cate shape-uri vrei si enjoy! La care nu-ti plac poti da Undo... :)

Post Reply