fit image in ellipse in pdflib - pdflib

I am using the pdflib library to generate the pdf for my online booking system. I'm new with pdflib library. I have tried a lot but not getting how I can set image into the ellipse with pdflib.
I'm using
$pdflib->ellipse ( 10 , 30, x_radius, y_radius);
It just draws the ellipse. How can I set image inside it ?

You can use clip method provided by PDFLib, like:
$pdflib->ellipse ( 10 , 30, x_radius, y_radius);
$pdflib->clip ();
$pdflib->fit_image($image, $x, $y, $options);
This will cut the image in the ellipse shape and also that image will fit into that.
Thanks!

Related

Information graphical visualization for web-page: Is there any better way instead of small PNG files?

Let's describe the task first:
I'd like to create a web-page with several rows of a text and a small (let's say 100 by 20 pixels) graphic for each one. Each graphic generated dynamically (so it will be a new one each time the page is loaded).
The only way I can imagine to my self is to create on server a new PNG file each time the row is indicated and include the link to this newly created file to HTML: <img src='row1graph.png'>.
If the page would be the single image - I could output it directly to the browser, but this is not my case.
So the question is: is there any better way to handle such images and skip unnecessary disk access operations?
You can serve an image from PHP rather than from a file - I mean you can have PHP dynamically create an image and serve it rather than having to have a file in your webserver's filesystem and having to refer to it by name in the src field of an tag in your HTML.
So, instead of
<image src="xyz.png" alt="..." size="...">
you can use
<img src="/php/thumb.php?param1=128&param2=45"/>
which causes the PHP script at /php/thumb.php to be called when the page is rendered. In that script, you can dynamically create the image (using extra parameters if you wish) like this:
<?php
header("Content-type: image/png");
$p1 = $_GET['param1'];
$p2 = $_GET['param2'];
// Create a 200x200 image
$im = imagecreatetruecolor(200,200);
$white = imagecolorallocate($im, 255, 255, 255);
$red = imagecolorallocate($im, 255, 0, 0);
// Here you can draw in the image, write on it, set any pixels, calculate any colours you wish
// Draw a white rectangle, then a red one
imagefilledrectangle($im, 50, 50, 100, 100, $white);
imagefilledrectangle($im, 75, 75, 150, 150, $red);
imagepng($im);
imagedestroy($im);
?>
I have omitted some code after the first 3 lines so you just see the technique rather than all the gory details of my code. The actual lines you are interested in are:
header(...image/png);
which tells the browser what type of stuff is coming - i.e. an image, and
imagepng();
which actually sends the stream of PNG data to the browser.
The code above produces this in the browser:
There's two ways to optimize small graphics in a web page. You can use the tile-set concept (all the graphics in a single image, with offsets based on e.g. background-position), or you can embed the PNG directly into the page as base-64:
<img alt="Embedded Image" src="data:image/png;base64,yourbase64image" />
The options have different merits based on file size and browser support. And of course, both can be combined - you can have an embedded tile-set.
Well if you want to avoid "unnecessary disk access" and since the image size is small you can use Base64 encoding. You can store the encoded strings in the database as well.
This way <img src='row1graph.png'> becomes...
<img src="data:image/jpg;base64,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"/>

OSM, OpenLayers and Google-maps always set to lon/lat (0,0)

I am trying to adapt the following OSM/OpenLayers example that uses Google maps to a project of mine
http://openlayers.org/en/v3.0.0/examples/google-map.html
I built the following page which is pretty straightforward :
http://185.8.104.235/testOSM/testOSM.html
The problem is that the map is always set to lon/lat (0,0) when the page loads, when I would like to zoom to different coordinates.
IOW, view.setZoom(5) works, while view.setCenter([47, 3]) doesn't...
Any suggestion ?
Thanks in advance.
You are setting the center in degrees (because you maybe think coordinates are in EPSG:4326) whereas defaut coordinates in OpenLayers 3 use EPSG:3857 aka Spherical Mercator.
You must make the conversion from EPSG:4326 to EPSG:3857
In your code,
var center = ol.proj.transform(view.getCenter(), 'EPSG:3857', 'EPSG:4326');
should be
var center = ol.proj.transform(view.getCenter(), 'EPSG:4326', 'EPSG:3857');
and
view.setCenter([47, 3]);
should be
view.setCenter(ol.proj.transform([47, 3], 'EPSG:4326', 'EPSG:3857'));

Libgdx collision detection with Physics Body Editor

I have recently started developing with Libgdx. Now, I'm looking at collision detection for custom shapes. In my case, I want to detect the collision of a shark with other objects. As a shark is a custom shape, I used the Physics Body Editor (https://code.google.com/p/box2d-editor/downloads/detail?name=physics-body-editor-2.9.2.zip&can=2&q=) to transform the shape into a json format.
I already have the code for the image drawing of the sharks and other stuff, but now I have no clue of how to implement the detection of collission with the json file. The tutorial on the phycics body editor website uses a different approach than I do.
Right now, I am drawing my shark like this in my render method:
batcher.draw(sharkAnimation, shark.getX(),
shark.getY(), shark.getWidth(), shark.getHeight());
sharkAnimation is a TextureRegion, and shark is an object with an X, Y, width and height.
The sharks width and height are variable, but maintain the same ratio's.
I already got the bodyeditor for libgdx, and I'm experimenting with the following code, but honestly I have no clue of how I should handle this.
BodyEditorLoader loader = new BodyEditorLoader(
Gdx.files.internal("data/shark.json"));
// 1. Create a BodyDef, as usual.
BodyDef bd = new BodyDef();
bd.position.set(0, 0);
bd.type = BodyType.DynamicBody;
// 2. Create a FixtureDef, as usual.
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.friction = 0.5f;
fd.restitution = 0.3f;
loader.attachFixture(????, ????, ???, ????);
Help is greatly apreciated.
You need to create a body, and then use the loader the attach the fixture you created in the editor to that body.
Body body = getWorld().createBody(bd);
loader.attachFixture(body, name, fd, scale);
The name is whatever you called it in the physics editor. Scale is how much you want to scale it by from the default size. Just use 1 if you don't want to change it.

How to replace bitmapData.copyPixels() with bitmapData.draw()

I'm trying to draw a level of my game using a tileset and a xml with the info. It works using copyPixels, but some tiles need to be flipped before they are drawn, so for that I need to use draw() instead of copyPixels(), but I can't get it to work. This is how I use copyPixes:
rectangleSelection = (desiredTile.x, desiredTile.y, tileWidth, tileHeight);
bmpData.copyPixels(tileset.bitmapData, rectangleSelection, new Point(pt.x, pt.y));
//pt.x and pt.y = tile location to be drawn().
How can I do the same thing using the bitmapData.draw() method? I just can't make it work.

Away3D (4.x broomstick) How do you convert global to local position of an object?

I am building a game that launches a ball at a target(Plane). The Plane is rotated back 45 degrees. I want to convert the global ball position(x,y,z) into the local coords of the target so I can detect where it hits.
Any ideas?
Use the target plane's inverseSceneTransform to transform the position vector of the ball. That should do it.
var localPosition : Vector3D;
localPosition = plane.inverseSceneTransform.transformVector( ball.position );
That should give you the ball's position in the plane's local space.
Above solution only works if the item/ball is directly on the stage. If it isnt, you should use ball.scenePosition!
item.position = targetContainer.inverseSceneTransform.transformVector(item.scenePosition);