BBC BASIC for Windows
Programming >> Graphics and Games >> Loss of image quality after GdipDrawImageRectRectI
http://bb4w.conforums.com/index.cgi?board=graphics&action=display&num=1308998124

Loss of image quality after GdipDrawImageRectRectI
Post by hans on Jun 25th, 2011, 10:35am

This program draws an image on the screen and a little part of the image. It saves the image in memory, to be used more times, so it won't lose time reloading it again.
But after using GdipDrawImageRectRectI to draw the little part of the image, the quality of the image is, especially with large photo's, greatly decreased when it is drawn on the screen again, as if it suffers from scaling artefacts.
In my case, loading and displaying an image of 5616 x 3744 pixels as a whole and as a part takes 214 centiseconds the first time. Redrawing it takes 0 centiseconds.
If you REM the line, starting with SYS `GdipDrawImageRectRectI`, the image is also not reloaded, but it does take a whole lot more time to draw the image again. In my case, loading and displaying the same image takes 84 centiseconds, and drawing the image again 78 centiseconds.

Is there a method to prevent this quality loss and still be able to redraw the image in memory very fast the second time, after using GdipDrawImageRectRectI?

Hans

Complete testprogram:

MODE 20 : VDU 5
PROC_gdip_image_init
ON CLOSE PROC_exit : QUIT
GDIP_image$=""
im$=@dir$+"35.jpg"
T=TIME : PROC_image(im$)
MOVE 100,106 : PRINT "Loading and drawing the image took "+STR$(TIME-T)+" centiseconds."
MOVE 100,72 : INPUT "Press a key to see the difference ";X$
T=TIME : PROC_image(im$)
MOVE 100,40 : PRINT "Drawing the image again took "+STR$(TIME-T)+" centiseconds."
END
REM ---------------------------------------------------------------------------------
DEF PROC_image(image$)
LOCAL wfile% : DIM wfile% LOCAL LEN(image$)*2+1
IF image$<>GDIP_image$ THEN
MOVE 100,138 : PRINT"Loading "+image$
SYS "MultiByteToWideChar",0,0,image$,-1,wfile%,LEN(image$)+1
SYS `GdipLoadImageFromFile`,wfile%,^GDIP_image%
ENDIF
SYS `GdipDrawImageRectI`, FN_gdipg, GDIP_image%, 0,0,800,510
REM Drawing a small part of the image at it's right side.
SYS `GdipDrawImageRectRectI`,FN_gdipg,GDIP_image%,600,500,126,80,200,150,126,80,2,0,0,0
SYS "InvalidateRect", @hwnd%, 0, 0
GDIP_image$=image$
ENDPROC
REM --------------------------------------------------------------------
REM Initialise GDI+
DEF PROC_gdip_image_init
LOCAL gdip%, R%, tSI{}
SYS "LoadLibrary", "GDIPLUS.DLL" TO gdip%
IF gdip% = 0 ERROR 73, "Couldn't load GDIPLUS.DLL"
SYS "GetProcAddress", gdip%, "GdiplusStartup" TO `GdiplusStartup`
SYS "GetProcAddress", gdip%, "GdipCreateFromHDC" TO `GdipCreateFromHDC`
SYS "GetProcAddress", gdip%, "GdipSetSmoothingMode" TO `GdipSetSmoothingMode`
SYS "GetProcAddress", gdip%, "GdipLoadImageFromFile"TO `GdipLoadImageFromFile`
SYS "GetProcAddress", gdip%, "GdipGetImageWidth" TO `GdipGetImageWidth`
SYS "GetProcAddress", gdip%, "GdipGetImageHeight" TO `GdipGetImageHeight`
SYS "GetProcAddress", gdip%, "GdipDrawImageRectI" TO `GdipDrawImageRectI`
SYS "GetProcAddress", gdip%, "GdipDrawImageRectRectI" TO `GdipDrawImageRectRectI`
SYS "GetProcAddress", gdip%, "GdipDisposeImage" TO `GdipDisposeImage`
DIM tSI{GdiplusVersion%, DebugEventCallback%, \
\ SuppressBackgroundThread%, SuppressExternalCodecs%}
tSI.GdiplusVersion% = 1
SYS `GdiplusStartup`, ^lGDIP%, tSI{}, 0 TO R%
IF R% ERROR 74, "GdiPlusStartUp failed"
ENDPROC
REM --------------------------------------------------------------------
DEF PROC_exit
GDIP_image%+=0 : IF GDIP_image% THEN SYS `GdipDisposeImage`, GDIP_image%
ENDPROC
REM -------------------------------------------------------------------
REM this function is the same as the one in the GDIPLIB library.
REM Return GDI+ graphics pointer
DEF FN_gdipg
LOCAL R%
PRIVATE G%
IF G% THEN = G%
SYS `GdipCreateFromHDC`, @memhdc%, ^G% TO R%
IF R% ERROR 71, "GdipCreateFromHDC failed"
SYS `GdipSetSmoothingMode`, G%, 2 TO R%
IF R% ERROR 72, "GdipSetSmoothingMode failed"
= G%

Re: Loss of image quality after GdipDrawImageRectR
Post by admin on Jun 25th, 2011, 8:48pm

on Jun 25th, 2011, 10:35am, hans wrote:
Is there a method to prevent this quality loss

As this isn't BBC BASIC-specific, I suspect you are more likely to receive an answer by asking on a GDI Plus forum.

Richard.

Re: Loss of image quality after GdipDrawImageRectR
Post by hans on Jun 27th, 2011, 08:53am

Yes, I do agree that my question is not BB4W specific. But I did find an elegant (at least in my opinion) solution in BB4W.
Instead of redrawing the image with GdipDrawImageRectI when needed, I save the firstly displayed image with the good quality with *SCREENSAVE and use that image with *DISPLAY. Now I only have to use the slower loading and showing GdipDrawImageRectI when the screen is resized, which is quite acceptable.

Thanks for your reply,

Hans.