I'm using TCPDF::Polygon() to render coastline (land) coordinates from a text file on top of a blue TCPDF::Rect(). The text file contains coastlines for the entire world, however by specifying a center latitude and longitude in the map projection, together with some multiplication to get a 'zooming' effect, I manage to display the desired area within the A4 page.
Problem:
As you can see by the image the coastlines are drawn all the way to the edge of the document (and beyond). Although most of the coastline coordinates from the text file are 'outside' the document's visible area they are still taking up some hundred kilobytes in the output file.
Is there a nice way to 'crop' the coastline-polygon, so that the coastlines fit nicely inside the blue area and the excess vertecies are completely excluded from the document (not taking up file space)?
Solution:
The 'cropping' I was looking for is done using clipping, as suggested by #Rad Lexus:
// Start clipping
$pdf->StartTransform();
// Draw clipping rectangle
$pdf->Rect($DOC_MARG, $DOC_MARG, $MAP_W, $MAP_H, 'CNZ');
// -- Draw all polygons here (land areas) --
// Stop clipping
$pdf->StopTransform();
Source: https://stackoverflow.com/a/9400490/2667737
To save space in the output file I check every pixel in each polygon (land area) and render only the polygons that has one or more pixels within the bounds of the page - also suggested by #Rad. In the example view in my first post, the size was halved using this method.
Thanks for the help!
Related
When you make a line profile of all x-values or all y-values the extraction from each pixel is clear. But when you take a line profile along a diagonal, how does DM choose which pixels to use in the one dimensional readout?
Not really a scripting question, but I'm rather certain that it uses bi-linear interpolation between the grid-points along the drawn line. (And if perpendicular integration is enabled, it does so in an integral.) It's the same interpolation you would get for a "rotate" image.
In fact, you can think of it as a rotate-image (bi-linearly interpolated) with a 'cut-out' afterwards, potentially summed/projected onto the new X-axis.
Here is an example
Assume we have a 5 x 4 image, which gives the grid as shown below.
I'm drawing top-left corners to indicate the coordinates system pixel convention used in DigitalMicrgraph, where
(x/y)=(0/0) is the top-left corner of the image
Now extract a LineProfile from (1/1) to (4/3). I have highlighted the pixels for those coordinates.
Note, that a Line drawn from the corners seems to be shifted by half-a-pixel from what feels 'natural', but that is the consequence of the top-left-corner convention. I think, this is why a LineProfile-Marker is shown shifted compared to f.e. LineAnnotations.
In general, this top-left corner convention makes schematics with 'pixels' seem counter-intuitive. It is easier to think of the image simply as grid with values in points at the given coordinates than as square pixels.
Now the maths.
The exact profile has a length of:
As we can only have profiles with integer channels, we actually extract a LineProfile of length = 4, i.e we round up.
The angle of the profile is given by the arc-tangent of dX and dY.
So to extract the profile, we 'rotate' the grid by that angle - done by bilinear interpolation - and then extract the profile as grid of size 4 x 1:
This means the 'values' in the profile are from the four points:
Which are each bi-linearly interpolated values from four closest points of the original image:
In case the LineProfile is averaged over a certain width W, you do the same thing but:
extract a 2D grid of size L x W centered symmetrically over the line.i.e. the grid is shifted by (W-1)/2 perpendicular to the profile direction.
sum the values along W
I have an image and I want to see how many pixels are in different parts of the image. Is there a software I can use to do this?
In Gimp, the "Histogram" dialog applies to the selection, so the pixel count displayed is the pixels in the selection (weighted by their selection level):
In the image below the selection covers the black circle which has a 100px radius. The Pixels value is close to 100²*Pi (314000 instead of 314159).
The Count is the number of pixels between the two values indicated by the handles at the bottom of the histogram.
Of course the selection can have any shape and be obtained with various tools.
I assume PS has something equivalent.
As a newbie of pdfbox user, I plan to extract data in a table, but tables with special formats, say with merged column headers should be processed with the help of table's borderlines. Therefore, the coordinates of the text and at least the table's horizontal borderlines should be extracted.
In order to extract the text from the table, I used PDFTextStripper to get the list of TextPosition objects; in order to extract the horizontal lines from the same page, I used PDFGraphicsStreamEngine to extract the list of stroked GeneralPath objects, and inside the stroked GeneralPath object, there is the corresponding Rectangle2D object representing the line (height = 0). But it seems that the aforementioned coordinates of TextPosition objects and the coordinates of GeneralPath objects are not in the same quadrant but with different Y-axis ray starting from the same origin.
According to my investigation, the origin of the TextPosition object is the top left corner, whereas the origin of the Rectangle2D is the bottom left corner, and the direction of each of the Y-axis differs from each other.
First, I would like to confirm that my investigation is right. If so I would like to get some hint about how to make the coordinates of Rectangle2D and TextPosition into the same quadrant.
Thanks in advance
I currently have 16 tiles, with individual images that make up 1 big map. I pan by transforming right at the beginning before any actual drawing with this:
GL.Translate(G_.Pan(0), G_.Pan(1), 0)
Then I zoom by doing this:
GL.Ortho(-G_.Size * 1.5 ^ G_.ZoomFactor, G_.Size * 1.5 ^ G_.ZoomFactor, G_.Size * 1.5 ^ G_.ZoomFactor, -G_.Size * 1.5 ^ G_.ZoomFactor, -1, 1)
G_.Size is a constant that only varies on startup depending on parameters, zoom factor ranges from -1 to -13
What I want to be able to do is check if 1 of the 16 tiles is within the visible area, so then I stop them drawing when they are not on screen. I had found some quite complex methods for doing it, but it was 3D and seemed like a lot of work for something that should be simple. I would of thought it would of been something like just checking if a point is within the bounds of visible area, but I have no idea on how to get the visible area.
Andon M Coleman already suggested you to implement projection volume culling (a generalized form of frustum culling). This is however outside the scope of OpenGL. You must understand that OpenGL is not a "magical" scene graph that does scene management and the likes. It's mere drawing API; what it does is putting shaded, textured points, lines or triangles on the screen and that's it. The rest is up to you, or the libraries you choose to implement it.
In the case of projection volume culling you're testing if a given piece of geometry intersects with the volume defined by the planes that form the borders of the volume. Your projection matrix defines such planes, specifically it transform the view space vertex position volume into the range [-1;1]×[-1;1]×[0;1] of perspective divided clip space. So by inverting the projection matrix and unprojection the corners of the [-1;1]×[-1;1]×[0;1] cube through that you determine the limiting planes of the projection volume in view space.
You then use that information to intersect your quads with the volume to see if they cross it, i.e. are in any way visible.
Is it possible to create a tiff file from a postscript-file (created from a pdf-document with readable text and images) into a tiff file without the text and only the images?
There is a way to create a tiff with no images, but I don't know how to use that way for my task. I need it to generate two images from a postscript-file - the first one with the images only and the second one with the text only.
Since the text is drawn over the top of the image, simple clipping won't do the job.
You can hack the text out by redefining the show operators to no-ops. Insert this after the %%Page comment line (where the page code really starts).
/show{pop}def
/ashow{3{pop}repeat}def
/widthshow{4{pop}repeat}def
/awidthshow{6{pop}repeat}def
/kshow{2{pop}repeat}def
/xshow{2{pop}repeat}def
/xyshow{2{pop}repeat}def
/yshow{2{pop}repeat}def
/glyphshow{pop}def
/cshow{2{pop}repeat}def
This will suppress all text-drawing operators. Edit: Now includes level 2 and 3 operators.
If you're trying to selectively suppress different kinds of elements, you may want to redefine only some of these operators. You can add % at the beginning of a line to comment-out a line of the code, keeping the full list intact (for future uses).
Another way to selectively suppress elements from a ps file is to use the powerful clipping mechanism.
144 288 72 72 rectclip % clip to a 1"x1" square 2" from the left, 4" from the bottom
Clip works with an arbitrary path. So you can even string together points in a connect-the-dots fashion to get the effect of a lasso-clip. Probably easiest if you print the image out and trace a grid to easily plot points for the trajectory.
100 100 moveto
200 200 lineto
300 100 lineto
500 500 lineto
200 700 lineto
closepath clip % clip to a non-rectangular convex polygon
Clipping will suppress all drawing operations that fall outside of the clippath while the clipping path is in effect.