|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
GDI+ and resizing a PictureBoxworks fine, but when I create the Graphics object, which takes a PictureBox hDC. It never draws outside the PictureBox original size if I make it bigger later, as if the Graphics object gets the hDC size only when it's created, and truncates any drawing to that. Is there a way to tell the Graphics object the new width and height? Also, hDC remains the same throughout the life of the control, except when you make the control bigger and AutoRedraw=True(because VB needs to create a bigger bitmap). When AutoRedraw=False, hDC property never changes when the PictureBox is resized(Whether bigger or smaller). So is there away to tell the Graphics object that the hDC has changed? In reality, I have to use double buffering, and the only method I found is to recreate the Graphics object. I hate to recreate the Graphics object each time while the user is resizing the form unless I have to. Below is sample code that demonstrates the problem. To try it, add a PictureBox, and 2 CommandButtons to Form1, then paste the following code. Run the project, then click on "Draw 1st Line", followed by "Draw 2nd Line". The second line should be larger and go to the other corner of the PictureBox, but it's truncated at the original size. API declarations came from the following source: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=37541&lngWId=1 There is a Type Library version at this location(You don't need it for the sample below to work): http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=42861&lngWId=1 In reality, I am using the type library version. I believe that VB only takes from it what I actually used, and EXE size would be smaller, plus I don't need to include the TLB or register it when distributing the application. The API declaration version is 2644 lines long! Option Explicit Private Type GdiplusStartupInput GdiplusVersion As Long ' Must be 1 for GDI+ v1.0, the current ' version as of this writing. DebugEventCallback As Long ' Ignored on free builds SuppressBackgroundThread As Long ' FALSE unless you're prepared to call ' the hook/unhook functions properly SuppressExternalCodecs As Long ' FALSE unless you want GDI+ only to ' use its internal image codecs. End Type ' NOTE: Enums evaluate to a Long Public Enum GpStatus ' aka Status Ok = 0 GenericError = 1 InvalidParameter = 2 OutOfMemory = 3 ObjectBusy = 4 InsufficientBuffer = 5 NotImplemented = 6 Win32Error = 7 WrongState = 8 Aborted = 9 FileNotFound = 10 ValueOverflow = 11 AccessDenied = 12 UnknownImageFormat = 13 FontFamilyNotFound = 14 FontStyleNotFound = 15 NotTrueTypeFont = 16 UnsupportedGdiplusVersion = 17 GdiplusNotInitialized = 18 PropertyNotFound = 19 PropertyNotSupported = 20 End Enum ' Quality mode constants Public Enum QualityMode QualityModeInvalid = -1 QualityModeDefault = 0 QualityModeLow = 1 ' Best performance QualityModeHigh = 2 ' Best rendering quality End Enum Private Enum SmoothingMode SmoothingModeInvalid = QualityModeInvalid SmoothingModeDefault = QualityModeDefault SmoothingModeHighSpeed = QualityModeLow SmoothingModeHighQuality = QualityModeHigh SmoothingModeNone SmoothingModeAntiAlias End Enum Private Enum FillMode FillModeAlternate ' 0 FillModeWinding ' 1 End Enum Private Enum GpUnit ' aka Unit UnitWorld ' 0 -- World coordinate (non-physical unit) UnitDisplay ' 1 -- Variable -- for PageTransform only UnitPixel ' 2 -- Each unit is one device pixel. UnitPoint ' 3 -- Each unit is a printer's point, or 1/72 inch. UnitInch ' 4 -- Each unit is 1 inch. UnitDocument ' 5 -- Each unit is 1/300 inch. UnitMillimeter ' 6 -- Each unit is 1 millimeter. End Enum Private Declare Function GdiplusStartup Lib "gdiplus" (token As Long, _ inputbuf As GdiplusStartupInput, _ Optional ByVal outputbuf As Long = 0) As GpStatus Private Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal token As Long) Private Declare Function GdipCreateFromHDC Lib "gdiplus" ( _ ByVal hdc As Long, graphics As Long) As GpStatus Private Declare Function GdipSetSmoothingMode Lib "gdiplus" ( _ ByVal graphics As Long, ByVal SmoothingMd As SmoothingMode) As GpStatus Private Declare Function GdipCreatePen1 Lib "gdiplus" ( _ ByVal color As Long, ByVal Width As Single, ByVal unit As GpUnit, _ pen As Long) As GpStatus Private Declare Function GdipDrawLineI Lib "gdiplus" ( _ ByVal graphics As Long, ByVal pen As Long, ByVal x1 As Long, _ ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long) As GpStatus Private Declare Function GdipDeletePen Lib "gdiplus" ( _ ByVal pen As Long) As GpStatus Private Declare Function GdipDeleteGraphics Lib "gdiplus" ( _ ByVal graphics As Long) As GpStatus Private Const WM_CLOSE = &H10 Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _ ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ lParam As Any) As Long Private GDIpLoaded As Boolean Private token As Long Private graphics As Long Private pen As Long Private Sub Form_Load() Dim GpInput As GdiplusStartupInput Me.ScaleMode = vbPixels Picture1.ScaleMode = vbPixels Me.Width = 600 * Screen.TwipsPerPixelX Me.Height = 300 * Screen.TwipsPerPixelY Picture1.Move 10, 10, 100, 100 Command1.Move Me.ScaleWidth - 100, 10, 90, 30 Command2.Move Me.ScaleWidth - 100, 50, 90, 30 Command1.Caption = "Draw 1st Line" Command2.Caption = "Draw 2nd Line" ' Load the GDI+ Dll GpInput.GdiplusVersion = 1 If GdiplusStartup(token, GpInput) <> Ok Then MsgBox "Error loading GDI+!", vbCritical PostMessage hWnd, WM_CLOSE, 0, ByVal 0& Exit Sub End If GDIpLoaded = True ' Initializations ' Initialize the graphics class - required for all drawing Debug.Print GdipCreateFromHDC(Picture1.hdc, graphics) ' Optional: Set Anti-Aliasing mode Debug.Print GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias) ' Create a red pen Debug.Print GdipCreatePen1(RGB(255, 0, 0) Or &HFF000000, 1, UnitPixel, _ pen) End Sub Private Sub Command1_Click() If Not GDIpLoaded Then Exit Sub End If ' Draw the first line Debug.Print GdipDrawLineI(graphics, pen, 0, 0, 100, 100) End Sub Private Sub Command2_Click() If Not GDIpLoaded Then Exit Sub End If ' Resize the PictureBox Picture1.Width = 200 Picture1.Height = 200 ' Draw a larger line, it's truncated at the original PictureBox size Debug.Print GdipDrawLineI(graphics, pen, 0, 0, 200, 200) End Sub Private Sub Form_Unload(Cancel As Integer) If GDIpLoaded Then ' Clean up GdipDeletePen pen GdipDeleteGraphics graphics ' Shutdown the GDI+ Dll GdiplusShutdown (token) End If End Sub "Nobody" <nob***@nobody.com> wrote in message The RGB values are reversed in GDI+, so use the function below instead. news:O5cM1kKPLHA.5644@TK2MSFTNGP04.phx.gbl... > ' Create a red pen > Debug.Print GdipCreatePen1(RGB(255, 0, 0) Or &HFF000000, 1, UnitPixel, > _ > pen) Alpha value need to be high enough, otherwise you may not see anything because it represents transparency level. Public Function RGBA(ByVal Red As Long, _ ByVal Green As Long, _ ByVal Blue As Long, _ ByVal Alpha As Long) As Long Dim result As Long If Alpha >= 128 Then result = &H80000000 End If result = result Or ((Alpha And &H7F&) * &H1000000) result = result Or (Red * &H10000) result = result Or (Green * &H100) RGBA = result Or Blue End Function "Nobody" <nob***@nobody.com> wrote in message Recreating the Graphics object works fine and seems unnoticeable, so I guess news:O5cM1kKPLHA.5644@TK2MSFTNGP04.phx.gbl... > ' Initialize the graphics class - required for all drawing > Debug.Print GdipCreateFromHDC(Picture1.hdc, graphics) this thread is closed unless someone has a better suggestion... On 16/08/2010 00:04, Nobody wrote:
> "Nobody"<nob***@nobody.com> wrote in message IIRC, this is the way it should be used.> news:O5cM1kKPLHA.5644@TK2MSFTNGP04.phx.gbl... >> ' Initialize the graphics class - required for all drawing >> Debug.Print GdipCreateFromHDC(Picture1.hdc, graphics) > > Recreating the Graphics object works fine and seems unnoticeable, so I guess > this thread is closed unless someone has a better suggestion... ..NET has the CreateGraphics() method you use when painting (or it does it implicitly in OnPaint), similar to the native GDI BeginPaint() function. -- Dee Earley (dee.ear***@icode.co.uk) i-Catcher Development Team iCode Systems (Replies direct to my email address will be ignored. Please reply to the group.) "Nobody" <nob***@nobody.com> wrote in message Maybe it's just me (these old eyes of mine are probably not quite what they news:O5cM1kKPLHA.5644@TK2MSFTNGP04.phx.gbl... > I am using GDI+ in one of my VB6 apps(mainly for anti aliasing support). used to be!), but I'm not really keen on GDI+ output when stretching images, at least not when reducing their size, which is the most common required stretching task when dealing with camera originals. The GDI+ NearestNeighbor mode is obviously not very good (about the equivalent of StretchBlt's COLOR_ON_COLOR, which is also the VB PaintPicture mode). The GDI+ HighQualityBilinear mode is smoother but very blurred, and the GDI+ HighQualityBicubic mode is the best of the three (as expected), but whilst having a decent smoothing it noticeably blurrs the image, making it look quite out of focus. In comparison, StretchBlt's HALFTONE mode gives almost as much smoothing whilst at the same time retaining all the sharpness of the original image. StretchBlt's HALFTONE output does not look out of focus at all. I would definitely say that StretchBlt's output certainly looks the best to me. Naturally, as with most things, it's "horses for courses" and there will be certain types of image (particularly computer drawn images) where the loss of focus of GDI+ HighQualityBicubic mode might be more than compensated for by the slightly better smoothing effect, and probably also when expanding the size of images (I haven't tried any comparisons on that yet because it is not something I normally need to do) but for my own needs I very much prefer StretchBlt's HALFTONE output to the GDI+ slightly out of focus output. Mike | Naturally, as with most things, it's "horses for courses" and there will It's my understanding that bicubic is recommendedbe | certain types of image (particularly computer drawn images) where the loss | of focus of GDI+ HighQualityBicubic mode might be more than compensated for | by the slightly better smoothing effect, and probably also when expanding | the size of images (I haven't tried any comparisons on that yet because it | is not something I normally need to do) for enlarging only -- bilinear for reducing....though I can't tell you now where I read that. "Mayayana" <mayayana@invalid.nospam> wrote in message Yeah, you're probably right. But I've just tried enlarging an image to 4.5 news:i4bakm$3r0$1@news.eternal-september.org... > It's my understanding that bicubic is recommended > for enlarging only -- bilinear for reducing....though I > can't tell you now where I read that. times its width and height using GDI+ HighQualityBicubic and compared it to the output of the standard GDI32 StretchBlt Halftone mode at the same size and I haven't changed my mind. I still prefer the output of StretchBlt, even when enlarging images. The sample I used was the small image of an eye from here: http://www.dpreview.com/learn/?/Glossary/Digital_Imaging/Interpolation_01.htm Neither GDI+ nor StretchBlt quite reach the quality of the PhotoShop output shown on that page, but they are both respectable and of the two I still prefer the StretchBlt output, which is very close to the smoothness of GDI+ but significantly sharper, at least to my eyes. Mike
Show quote
Hide quote
|
http://www.dpreview.com/learn/?/Glossary/Digital_Imaging/Interpolation_01.htm
| > It's my understanding that bicubic is recommended | > for enlarging only -- bilinear for reducing....though I | > can't tell you now where I read that. | | Yeah, you're probably right. But I've just tried enlarging an image to 4.5 | times its width and height using GDI+ HighQualityBicubic and compared it to | the output of the standard GDI32 StretchBlt Halftone mode at the same size | and I haven't changed my mind. I still prefer the output of StretchBlt, even | when enlarging images. The sample I used was the small image of an eye from | here: | | | Isn't halftone a dithering method that would lose| Neither GDI+ nor StretchBlt quite reach the quality of the PhotoShop output | shown on that page, but they are both respectable and of the two I still | prefer the StretchBlt output, which is very close to the smoothness of GDI+ | but significantly sharper, at least to my eyes. | colors? How does that work on a true-color system? The images on that page don't look very different to me, except the fractal method, which looks noticeably better. But I've never heard of "fractal interpolation", and the link to www.altamira-group.com seems to be dead. "Mayayana" <mayayana@invalid.nospam> wrote in message Well, the colour halftones I remember from my youth were the pictures in the news:i4cgd0$3a1$1@news.eternal-september.org... > Isn't halftone a dithering method that would > lose colors? How does that work on a > true-color system? old comic books (and later in photos in newspaper images) where the image was composed of dots that that differed in both colour and size, with a limited number of colours that was partly made up for by the fact that the dot size was not fixed, but those comic book halftones I recall from my youth were over half a century ago now and the details of the halftone method might have changed quite a bit since I was a lad! As far as your remark about the possibility of it losing colours is concerned, StretchBlt halftone certainly does not seem to have any problem at all dealing with full colour images. In fact I've just tested it on a 6338 x 4934 pixel .bmp photo which contains 3,694,204 unique colours. When I use StretchBlt halftone I get the following results: 6338 x 4934 pixels : 3,694,204 unique colours (original) 9507 x 7401 pixels : 4,685,815 unique colours (1.5 x 1.5) 4754 x 3700 pixels : 3,026,265 unique colours (.75 x .75) It certainly does not look to me as though StretchBlt halftone is having any problem at all dealing with lots of colours. As far as the StretchBlt halftone mode is concerned, I do not know the details of the algorithm it uses, or even if the name "halftone" in that respect refers to an adaption of the old early classic halftone methods or perhaps something that might now be quite different. What I do know is that, at least to my own eyes, reducing the size of photos using StretchBlt's halftone mode (which is about the only thing I ever do with it) produces results as good as any you can get from GDI+, and even better where sharpness is concerned (as is the case with my old eyes!). It might be that GDI+ does better when increasing the size of photos, but personally I never have the need to do that. If I did then I would certainly look into it and I would perform some tests and, if GDI+ turned out to be better at increasing the size of photos, then I would use it (although neither StretchBlt nor GDI+ is going to give you anywhere near the quality that you get from something like Adobe PhotoShop of course!). I've got nothing against using GDI+, it's just that the for reducing the size of photos (which is the only thing I normally do with StretchBlt) I actually prefer StretchBlt's halftone output to any of the three GDI+ outputs. > The images on that page [the three different GDI+ Actually they all look different to me, although the second and third are > methods] don't look very different to me . . . quite similar. > . . . except the fractal method, which looks noticeably better. Yes, it does, Lots better. But sadly neither StretchBlt nor GDI+ can use that method. StretchBlt will never be updated to use it of course, because GDI32 is dead in the water as far as Micro$oft is concerned. Perhaps one day, when all the Micro$oft employees stop watching their CEO dancing around on the stage like a deranged lunatic . . . http://www.youtube.com/watch?v=Y89wBYVHkY4&NR=1 .. . . and when they instead get on with some actual work, they might be able to buy some people from Adobe or somewhere who actually know what they're doing and get them to produce a "Micro$oft update" for GDI+ for them :-) Mike
Show quote
Hide quote
| > Isn't halftone a dithering method that would Thanks for that info. I asked because I didn't know what| > lose colors? How does that work on a | > true-color system? | | Well, the colour halftones I remember from my youth were the pictures in the | old comic books (and later in photos in newspaper images) where the image | was composed of dots that that differed in both colour and size, with a | limited number of colours that was partly made up for by the fact that the | dot size was not fixed, but those comic book halftones I recall from my | youth were over half a century ago now and the details of the halftone | method might have changed quite a bit since I was a lad! As far as your | remark about the possibility of it losing colours is concerned, StretchBlt | halftone certainly does not seem to have any problem at all dealing with | full colour images. In fact I've just tested it on a 6338 x 4934 pixel ..bmp | photo which contains 3,694,204 unique colours. When I use StretchBlt | halftone I get the following results: | | 6338 x 4934 pixels : 3,694,204 unique colours (original) | 9507 x 7401 pixels : 4,685,815 unique colours (1.5 x 1.5) | 4754 x 3700 pixels : 3,026,265 unique colours (.75 x .75) | | It certainly does not look to me as though StretchBlt halftone is having any | problem at all dealing with lots of colours. halftone does so I looked it up, and found this: http://support.microsoft.com/kb/168743 But based on your results it sounds like halftone can also perform a sort of anti-dither, filling in likely colors in an enlargement. I did a quick look around for fractal interpolation and found various things. It doesn't seem to be a clear-cut issue. One page I found was here: http://www.resampling.narod.ru/ Lots of methods... but no source code. Maybe one of these days when I have time I'll look into that. It looks like it could take a long time to get hold of straight VB code for these methods.
Show quote
Hide quote
"Mayayana" <mayayana@invalid.nospam> wrote in message Actually the page at the link you posted mostly concerns itself with the news:i4fcqg$k5v$1@news.eternal-september.org... > > > > [Mike Williams said] In fact I've just tested it on a > > 6338 x 4934 pixel .bmp photo which contains > > 3,694,204 unique colours. When I use StretchBlt > > halftone I get the following results: [snipped] > > Thanks for that info. I asked because I didn't know > what halftone does so I looked it up, and found this: > http://support.microsoft.com/kb/168743 > But based on your results it sounds like halftone > can also perform a sort of anti-dither, filling in > likely colors in an enlargement. GDI32 SetColorAdjustment function and so its initial mention of halftone StretchBlt limited itself to how it can use dithering to overcome the limitations of BitBlt's remapping when drawing a full colour 24 bit image into a lower colour depth display, such as a 16 bit display for example. But when you are using a halftone StretchBlt to reduce or enlarge the pixel size of an original 24 bit bitmap and to save the output as a new image (rather than simply draw it to the screen) then instead of using PictureBoxes you would normally load the original bitmap into a 24 bit DIB and ask StretchBlt to draw its output into another 24 bit DIB, and in that case it has the full sixteen million colours to work with in both DIBs regardless of the colour depth of the display on which your code is running. StretchBlt is then capable of calculating new colour values for various pixels (although I don't know the specific algorithm it uses) and it has the full sixteen million colours at its disposal and is not limited to the colours used in the original when it does that. Not that it often matters much these days of course, where almost all desktops and laptops are running full colour displays. By the way, thank you for the link to the SetColorAdjustment function. It is something I had briefly looked a long time ago but had almost totally forgotten about, so I'm glad you posted that link. I might look at it again now. There seem to be all sorts of filters that can be applied to StretchBlt, many of which look quite interesting. The only one I had ever used myself, when I briefly looked at it ages ago, was the contrast filter, but that particular filter did not work very well as I recall. On many photos it worked okay if you altered both the brightness and the contrast, but on some photos, particularly those that have an original average brightness level far removed from the 128 mid value, it was not possible to get a good contrast adjustment at all using SetColorAdjustment, regardless of what you did. In fact I seem to recall that was why I stopped using it and instead wrote code to perform the contrast adjustment pixel by pixel in straight VB code, which turned out to be just as fast as StretchBlt halftone contrast but which is capable of producing a high quality contrast on all images, regardless of their original average brightness level. Anyway, thanks again for the link. I'll probably have a look at SetColorAdjustment again. Mike |
|||||||||||||||||||||||