Change page format after writeHTML - html

I generate page using writeHTML under TCPDF. My page is made of 3 blocs (top, middle, bottom). I rotate the top one by 180 and middle one by 90.
Final page must be A4 landscape.
It works fine (as you can see on the snap) except for a small detail: as the middle part turn of 90°, this mean BEFORE the rotation the height of this part is higher than the heigt of the A4 landscape.
The only way I've found to have a correct display even with a middle block of great height (before rotation), is to perform the rotation using an A3 Portrait page. As on the picture.
So 2 questions:
Any idea of another way of doing?
If there is no other option, is it possible to generate the PDF in A3 portrait (using WriteHTML) and AFTER, crop the page to save (output) only the top part of the page, so to have a A4 landscape? (using TCPDF, not "manually")
For those interested: As I've dynamic data, I need to search each time for the center of rotation and the translation I must apply to the bootom block for it goes up against the middle block after the rotation. For that, I add "tcpdf method" tag on my HTML template, perform a writeHTML which call functions GetX, GetY and save the coord. for rotaton and also relative position of middle and bottom block (for bottom block translation)
Then I "rollback", set the coord in the template and perform a second writeHTML.

Lemme guess. If it's longer, the page breaks and it only rotates the content that had fit on the page while also possibly throwing off values you were expecting for GetX and GetY?
Disable the automatic page break and it should work as you expect.
$pdf->SetAutoPageBreak(FALSE, 0);
This way, it'll just draw off-page where it needs to without a page break interfering.
Edit: However I was wrong, as noted in the comment, that GetY would return a coordinate outside of the page. It does not.
So, we'll need to do our height check on a larger page, and then redraw on a new (properly sized) page once we know what we need to for layout, and destroy the original.
You can do that with transactions or with AddPage and DeletePage.
I tested with AddPage and DeletePage.
//.....
$pdf = new TCPDF_HELPER('L', 'pt',
array(8*72,5*72), true, 'UTF-8', false);
// set auto page breaks
$pdf->SetAutoPageBreak(FALSE, 0);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->setFontSubsetting(true);
$fontname = TCPDF_FONTS::addTTFfont(dirname(__FILE__).'/playtime.ttf', 'TrueTypeUnicode', '', 96);
$pdf->setFont($fontname, '', 16);
//I'm using a points and a ridiculous 19 inch by 19 inch custom size.
//We'll use this one to get the proper offset with `GetY`
$pdf->AddPage('L', array(19*72, 19*72));
$pdf->SetXY(1, 45);
$pdf->setFillColor(255,255,230);
$column = <<<EOT
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP</p>
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP</p>
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP ioj</p>
<p>WHITE APPLE COUNTRY HORSE STABLE BATTERY PIG SHEEP KANE CICI LOLIPOP ioj</p>
EOT;
//Get our multicell's final offset.
$pdf->WriteHTMLCell(80, '', '', 40, $column, 1, 2, 1, false, 'J', true);
$stopposition = $pdf->GetY();
//Now that we have our needed coordinates,
//Add a new page in our desired format.
$pdf->AddPage('L', array(8*72,5*72));
$pdf->StartTransform();
$pdf->Rotate(90, 40, 70);
$pdf->WriteHTMLCell(80, '', '', 40, $column, 1, 0, 1, true, 'J', true);
$pdf->StopTransform();
$pdf->SetX(20);
$pdf->SetY(-20);
$pdf->Write('', "End of column, pre-rotation: $stopposition pt");
//Delete our larger calculation page.
$pdf->DeletePage(1);
//.....

Even if EPB answer is a very interesting one and work in some cases, in my case the result was the same.
So i've found a different way of doing. It's NOT really a "pure answer" but a good trick.
I create my page in A3 Portrait and rotate the data in order to get all the data in the upper part.
Then, I use a tool named "pdfposter" which I call from PHP, in order to split the A3 portrait PDF in two A4 Landscape.
So, after the writeHTML() I do:
$path_a3 = __DIR__ . '/../tmp/a3.pdf';
$path_a4 = __DIR__ . '/../tmp/a4.pdf';
$pdf->Output($path_a3, 'F');
$pdfposter = "pdfposter -m a4 -p 2x1a4 ".$path_a3." ".$path_a4;
exec($pdfposter,$retArr, $retVal);
After that, I've a a4.pdf with two A4 pages.
Notice just one detail: the page made wih TCPDF with rotated data are NOT compatible with pdfposter 0.6! You have to install version 07.post1 (latest from Git).

Related

Cesium: Is it possible to make the trailing path thinner?

I'm using the Cesium library to simulate the satellite motion. This code is used to show the path:
path:{
leadTime:data.data_list[0].period/2,
trailTime:data.data_list[0].period/2,
width:1.5,
material: color
}
Is there a way to make the trailing path thinner?
As an example, the SpaceX video: http://youtu.be/rQEqKZ7CJlk?t=47m40s
Couple of comments here. First, with a width of only 1.5, altering the width is likely not the effect you want. Try using a solid color vs a faded color, such as by changing the alpha value. This should be more similar to what you're seeing in that video link.
But, currently Cesium does not support separate path materials for lead and trail times. If you really need both lead and trail paths shown with different colors/widths/etc, you have to insert a duplicate entity in your CZML (whose position can just be a reference to the primary entity position), such that one entity can have only a leadtime and the other has only a trailtime, and they use different path materials.
But if you have a satellite in a stable orbit, you there's a different approach you can take, because the thing keeps circling around the same path. You can use the StripeMaterial to make the orbit line fade from one side to the other.
Here's a live demo that loads simple.czml and replaces the Molniya's yellow orbit with a faded line. The solid part is the most recent trail of the satellite, and the faded part is much further back but serves to show where the satellite is headed next.
Cesium.Camera.DEFAULT_VIEW_FACTOR = 5.5;
var viewer = new Cesium.Viewer('cesiumContainer', {
shouldAnimate : true
});
Cesium.CzmlDataSource.load('../../../../Apps/SampleData/simple.czml').then(function(dataSource) {
viewer.dataSources.add(dataSource);
viewer.camera.flyHome(0);
viewer.clock.multiplier = 1800;
var entity = dataSource.entities.getById('Satellite/Molniya_1-92');
var fadedLine = new Cesium.StripeMaterialProperty({
// The newest part of the line is bright yellow.
evenColor: Cesium.Color.YELLOW,
// The oldest part of the line is yellow with a low alpha value.
oddColor: Cesium.Color.YELLOW.withAlpha(0.2),
repeat: 1,
offset: 0.25,
orientation: Cesium.StripeOrientation.VERTICAL
});
entity.path.material = fadedLine;
entity.path.leadTime = new Cesium.ConstantProperty(0);
entity.path.trailTime = new Cesium.ConstantProperty(3600 * 12);
});
Here you can play with the color, of course, but I would recommend keeping the same base color for even and odd. The withAlpha value of 0.2 on the oddColor here controls how faded the line gets, range is 0 to 1. The offsetvalue here can also be tweaked, to control the placement of the fade range. leadTime should be zero, and trailTime should be the orbit's period.

tesseract didn't get the little labels

I've installed tesseract on my linux environment.
It works when I execute something like
# tesseract myPic.jpg /output
But my pic has some little labels and tesseract didn't see them.
Is an option is available to set a pitch or something like that ?
Example of text labels:
With this pic, tesseract doesn't recognize any value...
But with this pic:
I have the following output:
J8
J7A-J7B P7 \
2
40 50 0 180 190
200
P1 P2 7
110 110
\ l
For example, in this case, the 90 (on top left) is not seen by tesseract...
I think it's just an option to define or somethink like that, no ?
Thx
In order to get accurate results from Tesseract (as well as any OCR engine) you will need to follow some guidelines as can be seen in my answer on this post:
Junk results when using Tesseract OCR and tess-two
Here is the gist of it:
Use a high resolution image (if needed) 300 DPI is minimum
Make sure there is no shadows or bends in the image
If there is any skew, you will need to fix the image in code prior to ocr
Use a dictionary to help get good results
Adjust the text size (12 pt font is ideal)
Binarize the image and use image processing algorithms to remove noise
It is also recommended to spend some time training the OCR engine to receive better results as seen in this link: Training Tesseract
I took the 2 images that you shared and ran some image processing on them using the LEADTOOLS SDK (disclaimer: I am an employee of this company) and was able to get better results than you were getting with the processed images, but since the original images aren't the greatest - it still was not 100%. Here is the code I used to try and fix the images:
//initialize the codecs class
using (RasterCodecs codecs = new RasterCodecs())
{
//load the file
using (RasterImage img = codecs.Load(filename))
{
//Run the image processing sequence starting by resizing the image
double newWidth = (img.Width / (double)img.XResolution) * 300;
double newHeight = (img.Height / (double)img.YResolution) * 300;
SizeCommand sizeCommand = new SizeCommand((int)newWidth, (int)newHeight, RasterSizeFlags.Resample);
sizeCommand.Run(img);
//binarize the image
AutoBinarizeCommand autoBinarize = new AutoBinarizeCommand();
autoBinarize.Run(img);
//change it to 1BPP
ColorResolutionCommand colorResolution = new ColorResolutionCommand();
colorResolution.BitsPerPixel = 1;
colorResolution.Run(img);
//save the image as PNG
codecs.Save(img, outputFile, RasterImageFormat.Png, 0);
}
}
Here are the output images from this process:

more minimaler cubism.js horizon chart from json example

Following up on a previous question... I've got my minimal horizon chart example much more minimaler than before ( minimal cubism.js horizon chart example (TypeError: callback is not a function) )
<body>
<div class="mag"></div>
<script type="text/javascript">
var myContext = cubism.context();
var myMetr = myContext.metric(function(start, stop, step, callback) {
d3.json("../json/600s.json.php?t0=" + start/1000 + "&t1=" + stop/1000 + "&ss=" + step/1000, function(er, dt) {
if (!dt) return callback(new Error("unable to load data, or has NaNs"));
callback(null, dt.val);
});
});
var myHoriz = myContext.horizon()
.metric(myMetr);
d3.select(".mag")
.call(myHoriz);
</script>
</body>
The d3.json() bit calls a server side .php that I've written that returns a .json version of my measurements. The .php takes the start, stop, step (which cubism's context.metric() uses) as the t0, t1, and ss items in its http query string and sends back a .json file. The divides by 1000 are because I made my .php expect parameters in s, not ms. And the dt.val is because the actual array of my measurements is in the "val" member of the json output, e.g.
{
"other":"unused members...",
"n":5,
"val":[
22292.078125,
22292.03515625,
22292.005859375,
22292.02734375,
22292.021484375
]
}
The problem is, now that I've got it pared down to (I think) the bare minimum, AND I actually understand all of it instead of just pasting from other examples and hoping for the best (in which scenario, most things I try to change just break things instead of improving them), I need to start adding parameters and functions back to make it visually more useful.
Two problems first of all are, this measurement hovers all day around 22,300, and only varies +/- 10 maybe all day, so the graph is just a solid green rectangle, AND the label just says constantly "22k".
I've fixed the label with .format(d3.format(".3f")) (versus the default .2s which uses SI metric prefixes, thus the "22k" above).
What I can't figure out is how to use either axis, scale, extent, or what, so that this only shows a range of numbers that are relevant to the viewer. I don't actually care about the positive-green and negative-blue and darkening colours aspects of the horizon chart. I just used it as proof-of-concept to get the constantly-shifting window of measurements from my .json data source, but the part I really need to keep is the serverDelay, step, size, and such features of cubism.js that intelligently grab the initial window of data, and incrementally grab more via the .json requests.
So how do I keep the cubism bits I need, but usefully change my all-22300s graph to show the important +/- 10 units?
update re Scott Cameron's suggestion of horizon.extent([22315, 22320])... yes I had tried that and it had zero effect. Other things I've changed so far from "minimal" above...
var myHoriz = myContext.horizon()
.metric(myMetr)
.format(d3.format(".2f"))
.height(100)
.title("base1 (m): ")
.colors(["#08519c", "#006d2c"])
// .extent([22315, 22320]) // no effect with or without this line
;
I was able to improve the graph by using metric.subtract inserting it above the myHoriz line like so: (but it made the numerical label useless now):
var myMetr2 = myMetr.subtract(22315);
var myHoriz = myContext.horizon()
.metric(myMetr2)
.format...(continue as above)
All the examples seem so concise and expressive and work fine verbatim but so many of the tweaks I try to make to them seem to backfire, I'm not sure why that is. And similarly when I refer to the API wiki... maybe 4 out of 5 things I use from the API work immediately, but then I always seem to hit one that seems to have no effect, or breaks the chart completely. I'm not sure I've wrapped my head around how so many of the parameters being passed around are actually functions, for one thing.
Next hurdles after this scale/extent question, will be getting the horizontal time axis back (after having chopped it out to make things more minimal and easier to understand), and switching this from an area-looking graph to more of a line graph.
Anyway, all direction and suggestion appreciated.
Here's the one with the better vertical scale, but now the numerical label isn't what I want:
Have you tried horizon.extent? It lets you specify the [min, max] value for the horizon chart. By default, a linear scale will be created to map values within the extent to the pixels within the chart's height (specified with `horizon.height or default to 30 pixels).

Getting doubles with animated sprite in libgdx

I am making a small simplistic game in libgdx to learn the basics and stuff. I tried my hand at having an animated character. One problem though, the first of the 4 frames shows fine but the second frame is shown and right next to it the third is rendered. The same for the third, it renders the last frame beside it. The first and last frame have no "Double" beside it though.
Character frames = C1 C2 C3 C4
1st frame - C1
2nd frame - C2 C3
3rd frame - C3 C4
4th frame(last) - C4
As for the code:
......
walk = new Animation(0.0015f, assets.leftframes);
.......
statetime += Gdx.graphics.getDeltaTime();
currentframe = walk.getKeyFrame(statetime, true);
batcher.draw(currentframe, character.x, character.y);
.......
I left out rest of the code to reduce clutter but I can show it if necessary.
Does anyone have any idea what the problem is?
Thanks in advance.
EDIT: Terrible paint skills but here is the picture of each frame as rendered:
Picture
It seems your second and third frames width are double of what they should be.
Check when you create your animation, all keyframes must have same width.
And your time between frames is too fast, try 0.2F.
EDIT (because your comment):
Thats what is wrong, every new frame gets a bigger width.
Replace this:
leftframes[x] = new TextureRegion(left, x * 32, 0, (x+1) * 32, 48);
With this:
leftframes[x] = new TextureRegion(left, x * 32, 0, 32, 48);

How to display two or more markers on the same location?

I have a question about the GOOGLE MAP API. If you have more than two data that share similar address, how do you show the Pins Drop on the same address?
Example
You have data such as the following:
Name=>Ray | Address=>Melon Park, California, USA ;
Name=>John | Address=>Melon Park, California, USA ;
Name=>Steve | Address=>Melon Park, California, USA
You want to display 3 Pins Drop for the similar address on Google Map.
The post linked above has some good advice. Your options are really:
Offset the markers slightly, so instead of displaying them all on the same they are all on really close to each other. Just add add or subtract small delta to each of them.
Use different icons for each location. If you know the maximum number of markers that could overlap (like 4?) at the same location, you could make your own rotated icons, so instead of pointing "down" in the typical teardrop shape they could point left, right, or up.
Handle the data overlap in your infowindow / UI.
Adding small delta will work like this (this script is written in PHP):
$random_num_lat = .00065 * mt_rand(1, 10); // delta to the lat value added
$random_num_lng = .00065 * mt_rand(1, 10); // delta to the lon value added
$lat=$row['lat']+$random_num_lat;
$lon=$row['lon']+$random_num_lng;
//now in loop it will be three `enter code here`marker display seperate to each other
while ($row = mysql_fetch_array($query)) {
echo ("addMarker($lat, $lon,'<b>$name</b><br/>$desc1');\n");
}
I achieved this using a "spiderfier" to "spiderfy".
There is a GoogleMaps v3 Spidifier available here (demo).
Leaflet.js can also load GoogleMaps v3 and has a beautiful clustering spidifier available here (demo).
Note: Following is a more of hack than a solution:
Write an algorithm that checks for repeated coordinates in array.
When a duplicate is found, add a small value such as 0.000001 to the found coordinates.
Note that the smaller the value the more you have zoom in to see the difference.