|
-
Dec 6th, 2014, 11:15 AM
#1
Thread Starter
Member
Unacceptable drawing resolution
I am writing a program that draws the position of the sun throughout the year. I had to write a program rather than use Excel because Excel wasn't able to perform enough calculations or "lift the pen" at the right times. Long story.
Anyway, it works, and is drawing everything I want it to draw. I am drawing directly on the form right now. I have drawn on picture boxes before but I'm not really sure what the advantage is. But the problem is the curves, delicate as they are, are far too pixelated to print. It is as if I drew it in MS Paint. The resolution just isn't good enough.
I'm looking for some kind of other option like an API I can print to. Some other canvas that I can access that won't have these limitations.
Ideas?
-
Dec 6th, 2014, 11:25 AM
#2
Re: Unacceptable drawing resolution
I do not see why a picture box should not be able to work just fine. Even drawing on the form should not be an issue. I would suspect the methods you are using. Or perhaps you are using a scale mode that is a bit to large.
-
Dec 6th, 2014, 11:29 AM
#3
Re: Unacceptable drawing resolution
The screen probably has less than 100 pixels per inch.
To print, you should try drawing the image on the printer, which will probably be at least 300, more likely 600 pixels per inch so not appear so pixelated.
The other method of reducing the appearance of pixelation will be doing anti-aliasing drawing.
Those are the topics, but I can't look around for examples to expand on it. Pressed for time.
-
Dec 6th, 2014, 11:34 AM
#4
Re: Unacceptable drawing resolution
Curves ? What kind of curves are you using, the primitive native basic .circle (circles and arc) ?
At any rate, two things :
- Yes picture boxes are a good idea.
- Most all serious drawing of intermediate level is achieved through GDIP (gdi+) calls, where you will get beautiful antialiased lines. There's a learning curve to it but well worth it!
-
Dec 6th, 2014, 12:12 PM
#5
Re: Unacceptable drawing resolution
The other way is to use a picturebox at 3X the size of your form, make the drawing there and copy with resize in the form. So you get a soft image...and making your drawing size independent, you have the rendering routine too for printer.
-
Dec 6th, 2014, 12:23 PM
#6
Re: Unacceptable drawing resolution
 Originally Posted by Navion
- Most all serious drawing of intermediate level is achieved through GDIP (gdi+) calls, where you will get beautiful antialiased lines. There's a learning curve to it but well worth it!
Challenge for the OP is probably recalculating how the curves are created. He mentioned "lifting the pen". This could mean the curves are drawn via individual pixels? GDI/GDI+ use 4 points (x,y) to render arcs.
Suggestion. Play with the Arc and/or ArcTo APIs and see if you can get what you want. It won't be anti-aliased. But if you can get that working, then that would be easily moved into GDI+ which will get you anti-aliasing. In other words, if you are not familiar with GDI+, maybe verifying the APIs work well enough for "proof of concept" is worthwhile. Then if it's good, learn enough GDI+ to convert the code to its functions which are very close to GDI's in this case. GDIpDrawArc has degrees involved whereas GDIPpDrawCurve uses points
Last edited by LaVolpe; Dec 6th, 2014 at 12:34 PM.
-
Dec 6th, 2014, 12:36 PM
#7
Thread Starter
Member
Re: Unacceptable drawing resolution
Well, there is another problem that I haven't mentioned yet. It needs to be printed very exactly, as it is metric sensitive. It is actually tracing the shadow of a gnomon throughout a year. The arcs are actually made with lines connecting points. Anti-aliasing would be good, but a lot more resolution would be better.
The way I have tried it to start with was separating the drawing into multiple images and piecing them together in photoshop and then eyeballing it all to the right measurement. I was very dissatisfied with that.
I think I will try making a huge picture box to start with, as suggested by georgekar, and if that doesn't work out, maybe I'll look into GDI/GDI+, which is sounding a little scary right off.
Thanks for the suggestions!
-
Dec 6th, 2014, 03:17 PM
#8
Re: Unacceptable drawing resolution
Your problem in that way as I suggest may or may not solved. The problem is from the scale you use. Using 15 twips per pixel if you need to print three points that have a distance less than 15 twips then maybe you see one pixel or two pixels, or three in a 2d canvas. Changing the size by a factor 3 you have real 45 twips per pixel. Because finally you resize it to 1/3, you may think that this is the same as you didn't.use the large picture box. But in the resample process we have a 2d interpolation, so maybe pixels from other lines give us something different, from what we expect without use of the big picture. So for doing a controlled output you have to change the accuracy for calculations according the dpi you use to render, and use line size according the size factor.
Last edited by georgekar; Dec 6th, 2014 at 03:21 PM.
-
Dec 6th, 2014, 03:24 PM
#9
Re: Unacceptable drawing resolution
 Originally Posted by ctullar
Well, there is another problem that I haven't mentioned yet. It needs to be printed very exactly, as it is metric sensitive.
Then - by all means - render it into a PDF directly (which is a resolution-independent Vector-Format) -
using a Library which in its Drawing-Methods allows Coord-Parameters in Double-Precision, which
will come out in exactly the same dimensions (and Page-Offsets) you specified at Drawing-Time
(take note, that this PDF-rendering will *not* need any "PDF-Printer-Driver" - the format is written
directly by the Library itself).
The very same library can be used, to render your OnScreen-Preview (or -Interactions) re-using the
very same Drawing-Routines you already have in place for the PDF-Output.
On vbRichClient.com you will find this currently most complete and powerful Graphics-Toolset
for VB6 - it is based on the platform-independent cairo-library - it's freeware and *much* more
convenient to use than e.g. GDI+ (since everything is fully encapsulated in easy to use Classes,
no Handle-Freeing or anything to take care of).
On the above mentioned WebSite you will also find a very complete Cairo-Tutorial-Download,
which contains about 20 VB-Code-DemoFolders (ordered from easy to advanced) - but already the
first few simple Tutorial-Projects (1 to 6 or so) will bring you up to speed with Curve- and
Line-Drawings, Scale- and Rotate-Methods etc.
 Originally Posted by ctullar
The arcs are actually made with lines connecting points.
Then you will appreciate perhaps, that you will be able to lower your amount of
"supporting-points", since the Cairo-Wrapper-lib supports a decent BSpline-
Interpolation between Points of a Polygon (based on Bezier-Curves).
 Originally Posted by ctullar
Anti-aliasing would be good, but a lot more resolution would be better.
Both is a given, since it is primarily a Vector-Library, which works resolution-independent.
Just give it a try - nothing you need to be scared of in my opinion - if you can handle
VBs Line and Circle methods, then you can also handle the DrawLine- and Arc- and
Polygon-methods of this library.
Olaf
Last edited by Schmidt; Dec 6th, 2014 at 03:34 PM.
-
Dec 6th, 2014, 05:09 PM
#10
Re: Unacceptable drawing resolution
Just uploaded a somewhat simpler PDF-creation example than the one which is included in the Cairo-Tutorial-Download:
http://www.vbforums.com/showthread.p...rawingRoutine)
Just ask, in case you run into difficulties, adapting it to your problem.
There's quite a lot which can be adjusted and simplified, when you use a good matching Scalemode
against a given cairo-surface...
E.g. with the offered Double-Precision, you could ensure a Scale on your Surface beforehand, which
would then allow you to put out Drawings even in "Parsec-units" if you want -
in case that simplifies ones thinking (or the generation of Polygon-Coordinates from existing Formulas or approaches).
Olaf
-
Dec 6th, 2014, 05:34 PM
#11
Re: Unacceptable drawing resolution
@Schmidt,
I believed that your approach is the best for the results. But you have to tell that using that CAIRO schema, need to forget about vb forms and the use of an IDE to manipulate it.
Is in any way in your intention to make the VB IDE to work on CAIRO forms, using an ADD on, to make the things easier for us to adopt your style?
-
Dec 6th, 2014, 07:27 PM
#12
Thread Starter
Member
Re: Unacceptable drawing resolution
Olaf,
That is quite an impressive compilation of tools. It looks like Spline Interaction is where I need to start. Then pdf. Thanks a lot for the link.
Chris
-
Dec 6th, 2014, 08:03 PM
#13
Re: Unacceptable drawing resolution
 Originally Posted by georgekar
@Schmidt,
I believed that your approach is the best for the results. But you have to tell that using that CAIRO schema, need to forget about vb forms and the use of an IDE to manipulate it.
Is in any way in your intention to make the VB IDE to work on CAIRO forms, using an ADD on, to make the things easier for us to adopt your style?
George, the new Form- and Widget-Engine is only one smaller part *on Top* of the cairo-graphics-
rendering-capabilities (which are separate, and can be used against Forms or PictureBoxes or
all other Containers which offer either a StdPicture-property or an .hDC to receive the Output
of intermediate Drawings which took place on an intermediate Cairo-Surface. In the case of a normal
Image-Surface - we talk only about an InMemory-Bitmap, basically just like a "32bpp-DIB on steroids").
For example - the complete Cairo-Tutorial, which is downloadable at the first Link on this WebPage here:
http://vbrichclient.com/#/en/Demos/GUI/
is only working against normal VB-PictureBoxes or VB-UserControls as the "receiving Container
of final cairo-Surface-Output".
Or look at this example here, which accomplishes the same thing as the Online-Demonstration (a Flash-App)
is doing (with a transversal animation of a Sinus-Wave - and also its longitudinal-representation).
http://www.vbforums.com/showthread.p...representation
The VB-Version covers this animation completely - in the same (or better) quality - in only 40 or so
lines of VB-Code, without any API-Declares - and all rendered directly into a VB-Form(hDC).
@Chris
the last mentioned "transversal/longitudinal-wave-animation-demo" is another example (not contained in the
Cairo-Tutorial), which shows how to handle Spline-Interpolations with an "reduced amount of supporting points"...
e.g. the Sinus-wave at the Top of the screenshot, is constructed from only the amount of Polygon-Points
you see visualized as blue circles.
BTW, ... good idea, to start with OnScreen-Output (created in the normal DIB-like Image-Surfaces)
first - when you have a nice Drawing-Routine put together, then it would be time, to let the Drawing-
Commands run against a PDF-Surface - but maybe ask here again - or in a new Thread - when you
reached that point.
Olaf
Last edited by Schmidt; Dec 6th, 2014 at 11:14 PM.
-
Dec 7th, 2014, 06:00 AM
#14
Re: Unacceptable drawing resolution
From the OP;
>are far too pixelated to print.
After 13 posts it seems we have still not established how the graphics are being printed.
Are you printing the graphics directly onto the printer or are you copying graphics drawn on the screen to the printer?
-
Dec 7th, 2014, 10:10 AM
#15
Thread Starter
Member
Re: Unacceptable drawing resolution
I hadn't decided how I was going to make it work, actually. I have very little experience with printing in vb. In the past, I always printed what was basically a glorified screen shot. But I really like the idea of printing to a pdf and retaining my scale. Ultimately, I have a bunch of curves that have to be exactly transferred to paper, or more likely some other medium. Since it is tracking the sun and it is outside, it will likely be etched into metal. But I will experiment with paper first, obviously.
-
Dec 7th, 2014, 05:17 PM
#16
Re: Unacceptable drawing resolution
Ok, first things first..
From what you are saying, standard VB graphics routines will give you sufficient quality and resolution if you take care of using them the proper way.
Working directly with the printer can eliminate a lot of more complex intermediate steps, such as antialiasing, making large images for better printout, printing to pdf's .. etc, etc.
Also, the routines will work on any printer, printer size, printer resolution (my printer printed that sample at 1200 dpi with lfs=12).
Using the standard printer drivers, and minus the fills (including the fills on many vector devices), this little code will output on plotters and CNC equipment too, at the maximum resolution of the output device without having you write a single line of code more.
At any rate, this snippet is not the final solution of your coding needs... just an entry example into matching sizes for both the screen and raster or vector output devices.
But the more important thing here is that your graphics will always be precise in scaling and the printer output will be more than satisfactory.
Code:
Dim lsf ' linescalefactor..... make this variable module level
Private Sub Form_Load()
'setup Printer
Printer.Orientation = vbPRORLandscape
Printer.ScaleMode = vbInches
Picture1.Font = "Tahoma"
' setup picturebox to match printer in size and units
' this will give you a large picture that the form can show on just about any monitor
Picture1.Appearance = 0
Picture1.BorderStyle = 0
Picture1.Width = Picture1.ScaleX(Printer.ScaleWidth, vbInches, vbTwips)
Picture1.Height = Picture1.ScaleY(Printer.ScaleHeight, vbInches, vbTwips)
Picture1.ScaleMode = vbInches
Picture1.AutoRedraw = True
Picture1.Font = "Tahoma"
End Sub
Private Sub Command1_Click()
' print to both the picturebox and the printer calling the same routine
drawMyStuff Picture1
drawMyStuff Printer
End Sub
Sub drawMyStuff(p1 As Object)
' in this procedure, write up your graph in page coordinates common to both : inches
' same procedure will print identical both on printer and on printer box
' everything here is in inches, except font sizes, which are designed to match screen and printer anyway
Rem set a linewidth scale factor to make lines a similar weighh on picture and printer
lsf = IIf(TypeOf p1 Is Printer, 6, 1)
' draw a header box on top of page quarter inch down, one inch high
xx1 = p1.ScaleWidth * 0.02
xx2 = p1.ScaleWidth * 0.98
yy1 = 0.25
yy2 = yy1 + 1
drawHeader p1, xx1, yy1, xx2, yy2, 1, 5, vbBlue, vbBlack, vbWhite, 48, "Earth Around The Sun"
'center of the sun
cx = p1.ScaleWidth * 0.5
cy = p1.ScaleHeight * 0.55
'print a sun in the middle of the page
drawOrbit p1, cx, cy, 5, 0 'all of it
drawPlanet p1, cx, cy, 2.5, 1, vbYellow, 5, vbRed
drawOrbit p1, cx, cy, 5, 1 'only the front part
'print earth
drawPlanet p1, p1.ScaleWidth * 0.7, p1.ScaleHeight * 0.7, 0.75, 1, vbBlue, 3, vbBlack
xx1 = 0.25
xx2 = xx1 + 3
yy1 = 7.25
yy2 = yy1 + 0.5
drawHeader p1, xx1, yy1, xx2, yy2, 1, 2, vbWhite, vbBlack, vbBlack, 12, "Graph by Yours Truly"
If TypeOf p1 Is Printer Then p1.EndDoc
End Sub
Sub drawOrbit(p1 As Object, xx1, yy1, radius, num)
Pi = 3.1415926
p1.FillStyle = vbFSTransparent
p1.DrawWidth = 3 * lsf
If num = 0 Then
p1.Circle (xx1, yy1), radius, vbBlack, , , 0.3
Else
p1.Circle (xx1, yy1), radius, vbBlack, Pi, Pi * 2, 0.3
End If
End Sub
Sub drawPlanet(p1 As Object, xx1, yy1, radius, lw1, color1, lw2, color2)
p1.DrawWidth = lw1 * lsf
p1.FillStyle = vbFSSolid
p1.FillColor = color1
p1.Circle (xx1, yy1), radius
p1.DrawWidth = lw2 * lsf
p1.FillStyle = vbFSTransparent
p1.Circle (xx1, yy1), radius, color2
End Sub
Sub drawHeader(p1 As Object, xx1, yy1, xx2, yy2, lw1, lw2, color1, color2, color3, fsize, msg$)
p1.FillColor = color1
p1.DrawWidth = lw1 * lsf
p1.Line (xx1, yy1)-(xx2, yy2), color1, BF
p1.DrawWidth = lw2 * lsf
p1.Line (xx1, yy1)-(xx2, yy2), color2, B
p1.FontSize = fsize
p1.FontBold = True
p1.ForeColor = color3
xx3 = xx1 + (xx2 - xx1) / 2
yy3 = yy1 + (yy2 - yy1) / 2
xx4 = xx3 - (p1.TextWidth(msg$) / 2)
yy4 = yy3 - (p1.TextHeight(msg$) / 2)
p1.CurrentX = xx4
p1.CurrentY = yy4
p1.Print msg$;
End Sub
-
Dec 7th, 2014, 06:27 PM
#17
Re: Unacceptable drawing resolution
For fonts is better to do a trick
You want to scale by a factor the letters, and put them in YourObject, selecting the right FontSize
YourOject.FontSize = 14.25 * factor
But YourObject set the Font size in the nearest valid value.
So you get this back
factor = YourOject.FontSize / 14.25
So now you hold a factor that is valid for your basic letters.
Now from that point you use this new factor to draw any line...
You have to inform for the actual zoom...as a feedback. But you don't want to produce a second pass from drawing rutine. So by using a flag temporary you block any action. The flag restored to previous state when feedback done. (The feedback maybe a change in the value in a scroll bar)
So we need a flag, and the factor manipulation to have perfect align text in any situation.
-
Dec 8th, 2014, 12:15 AM
#18
Re: Unacceptable drawing resolution
That depends... Some fonts use only fixed sizes, some others are infinitely scalable. Tahoma is one of the later. It will always print exactly matched from picture to printer. No need for a font scale factor.
Code:
p1.DrawWidth = 2 * lsf
cx = p1.ScaleWidth * 0.5
cy = p1.ScaleHeight * 0.5
radius = 3.5
nbsteps = 32
a$ = "O"
For i = 1 To nbsteps
xx1 = cx + radius * Cos(i / nbsteps * 8 * Atn(1))
yy1 = cy + radius * -Sin(i / nbsteps * 8 * Atn(1))
p1.Circle (xx1, yy1), p1.ScaleX(8 + i, vbPoints, vbInches) / 2, vbBlue
p1.FontSize = 8 + i
p1.CurrentX = xx1 - p1.TextWidth(a$) / 2
p1.CurrentY = yy1 - p1.TextHeight(a$) / 2
p1.Print a$;
Next
Last edited by Navion; Dec 8th, 2014 at 12:18 AM.
-
Dec 8th, 2014, 05:39 PM
#19
Re: Unacceptable drawing resolution
But you use integers (step for i in 1 to nbsteps are 1). So this is not the case. The problem is from using single to make the font size. Single at least when you want to zoom text with graphics.
-
Dec 8th, 2014, 06:09 PM
#20
Re: Unacceptable drawing resolution
Works with floats too.
Code:
p1.Circle (xx1, yy1), p1.ScaleX(18 + i * 0.25, vbPoints, vbInches) / 2, vbBlue
p1.FontSize = 18 + i * 0.25
-
Dec 8th, 2014, 06:41 PM
#21
Re: Unacceptable drawing resolution
The problem isn't in quarters (except from some old fonts). We can display text anywhere in pixel position, but for size there is a problem. We can't fit the chars between any two heights, we have to leave space.
You show me some code. Ok. But do what I do for trick above. Set a fontsize and then see if it is equal with the setting. Add to 12 a .0034 and what you get??
-
Dec 9th, 2014, 01:41 AM
#22
Re: Unacceptable drawing resolution
Let's not split pixels in 4 here, shan't we? Using a good font in points for both picturebox and printer at 600 dpi is more than good enough for loosely centering a string of text in a header box 4 times the size lolll
-
Dec 9th, 2014, 06:04 AM
#23
Re: Unacceptable drawing resolution
The problem isn't if we can fit in 1200dpi text and graphics...but if the scale of text is in same ratio as for the drawing. So the question is...can the font have same scale with other drawings in any desired scale? The answer is NO. In science every question can be answered...My answer has the fact that when we set a fontsize then we see if the setting is as we expect...and we see that it isn't. Just do that
Private Sub Form_Load()
Form1.FontName = "TAHOMA"
Form1.FontSize = 12.345
Caption = Form1.FontSize = 12.345
End Sub
And that is the prove (computers are science first)
-
Dec 10th, 2014, 06:24 AM
#24
Re: Unacceptable drawing resolution
Your problem is that UI widgets and all instances of StdFont are bound to the screen's device context.
See PRB: Setting Printer.Font.Size with StdFont Gives Wrong Values.
So when you change the font size for a TrueType/OpenType scalable font it gets rounded to a size in whole pixels that is also a whole multiple of 1/10000 of a Point. See 2.4.12 StdFont:
ulHeight (4 bytes): An unsigned integer that specifies the height, in ten-thousandths of a point, of the font. MUST be greater than zero and less than or equal to 655350000.
That internal field is directly mapped to the .Size property's Currency value.
So if you have a printer with much higher dot resolution (let's say 600 DPI):
Code:
Private Sub Form_Load()
Printer.Font.Name = "Tahoma"
Printer.Font.Size = 12.345
Caption = Printer.Font.Size
End Sub
... reports a much finer approximation of the requested value, such as 12.36 or so.
The higher the resolution of the printer, the closer you come to the exact font height (size) requested. The same applies to display fonts when you use higher DPI settings.
Last edited by dilettante; Dec 10th, 2014 at 06:28 AM.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|