How to draw warped text like this picture in libgdx?
There are different methods to do this – and they do not come standard in libgdx, so you will have to implement one yourself.
Convert the text to outlines. Warp each of the coordinates. Draw polyfilled objects using these warped coordinates. This is what professional software such as Adobe Illustrator and CorelDraw do.
Draw the text into a bitmap. Warp the bitmap. For a better result, draw the bitmap at twice the output size so you can use subsampling.
(Based on the rather poor quality of the sample image) Draw each of the characters slightly rotated. You can base the amount of rotation on the total number of characters (quick, dirty, and simple), or ever so slightly improve it by using the individual widths of each character to determine its relative position inside the entire string, and base the amount of rotation on that.
Are you going to use this picture for some motion or you just need it for display? If it's the latter why don't you just draw it in gimp, photoshop or even paint and position it/scale it on where you need it on the screen as normal sprite/actor?
Related
however, i have a weird issue, when drawing, it seems the outside 1px of an image is stretched to fit a rectangle, but the inside is only stetched to an extend, i was drawing to 48x48 tiles, but drew a 500x500 tile to show the issue. [ 500x500 draws fine ]
the worst part seems to be, it chooses when to stretch and not to stretch. and also what to strech. im sorry this is hard to explain but i have attached a image that i hope does a better job.
it could just be misunderstanding how to use a draw with spritebatch
edit: Tile is 48x48 not 64x64, ive just been working all day.
This is because you are not rendering "pixel perfect" which means your image does not line up with the pixel grid of your monitor. A quick fix might be to set a linear filter for your textures, since by default it uses nearest and thus a pixel on the screen will inherit the closest color it can get. A linear filter will interpolate colors and make that line "look" thinner.
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
If you are using texturepacker you can do this in one go by altering it's settings.
texturePackerSetting.filterMin = Texture.TextureFilter.Linear;
texturePackerSetting.filterMag = Texture.TextureFilter.Linear;
Or you could edit the atlas file itself by by changing the filter parameter to:
filter: Linear,Linear
This obviously costs more power since it needs to do more calculations for each pixel you drawn to the screen but I would not worry about this until your drawing is starting to get a bottleneck.
Another solutions is to draw pixel perfect which means you need to set your viewport to the size of the device gdx.graphics.getWidth, gdx.graphics.getHeight, in other words a ScreenViewport and draw your textures at exact sizes you want them. Of course this means a screen with more pixels sees more of your game world then a screen with less pixels and the more pixels a device has the smaller your textures will look. Another drawback of this is that you have to forget about any zooming or draw sprites for each level of zoom so they line up with the pixel grid of the device again.
I create png Images from short pieces of text to be used as floating labels, prompts, speechbubbles, etc in a 3D graphics application. Occasionally some of my text needs to be rotated. Unfortunately the 3D application does not provide rotation for this kind of image. I have it fully working for both rotated and non-rotated text, and even the rotated images are drawn correctly if the text is short, but if I use a longer string, it gets cut off because the BufferedImage is not sized to handle it. Do I need to use trigonometry to size it? I know I could always use a huge rectangle in the BufferedImage, but that seems inelegant.
Note that I only ever create single lines of text. If I need multiple lines occasionally, I use multiple images and stack them, it just works better for me that way.
I thought about the best way to draw a picture in OpenGL / JOGL.
I currently program a Game and it is my goal to save the information about a picture in a text file instead of saving the picture.
My idea was to program a method that saves every pixel information (RGB) at the position of X and Y.
Then I draw every pixel and it is finished.
What you think about that idea?
You should simply use TextureIO to make a texture from your picture and use this texture with 4 vertices that have some texture coordinates while drawing. glReadPixels() is very slow, reading each pixel of a picture would take a lot of time, saving its content as a text file would require a lot of memory (saving it as a compressed image in a loss-less format like PNG might be worth a try), drawing each pixel one by one would be a lot slower than drawing a texture. derhass is right. You could vectorize your picture (make a SVG from it) but you would have to rasterize it after or you would have to implement some rendering of vectorized contents and it would be probably slower than using a texture. I'm not sure you really need an offscreen buffer.
I had a similar problem when I began working on my first person shooter. I wasn't using JOGL at the very beginning, I reused the source code of someone else, it relied on software rendering in an image, it was very slow. Then, I used JOGL to draw each pixel one by one instead of using Java2D, it was about 4 times faster on my machine but still very slow for me. At the end, I had to redesign the whole rendering to use OpenGL for what it is for as derhass would say, I used triangles, quads and textures. The performance became acceptable and this is what you should do, use OpenGL to draw primitives and clarify what you're trying to achieve so that we can help you a bit better.
From the above image if I want a portion behind the RED Rectangle I can easily get it,
but the issue I cannot get the portion behind the Yellow Rectangle because it is rotated.
So how can I get a portion of an image from a rotated shape on it?
For example my goal is to get a portion of an Image where the rectangle is located on the image. if someone rotates this rectangle by an x degree [in whatever direction] then it is getting difficult to extract the exact portion of an image after applying rotation.
Any suggestions?
Here a more lengthy description of a possible approach. I do not know the Java2D drawing API very well but if I remember correctly it has the capabilities to do what is required.
First you have to figure out the translation and rotation of the subregion you want compared to an equally size rectangle located straight in the upper left corner in the image. Then invert this transformation.
Make a graphics context which is backed by a bitmap in memory. This one should have the size of the subimage you want. Setup the inverse transformation you calculated earlier on the context and draw your image at position 0,0. As Java2D will take the transformation into account you should now get the sub image you want in the memory bitmap.
Mihir, I think you might be getting distracted by the rotation/AffineTransform aspects of this challenge and it is leading you down the wrong road. Also keep in mind that I don't totally know what you mean by "get" here -- do you want to save out the highlighted region to an image? Do you want to render it as a watermark on another image? etc... I'll just try and answer in the general case to get you down the right track.
What you want is the content from the image defined by the polygon in yellow in your image above; ignoring the fact that it looks like a rotated rectangle.
It is late and I am missing a step in here, but I think this will get you 90% of the way there and clarify the last piece (Graphics2D.setClip) that you need.
Create a java.awt.Polygon that defines the region around the area you want.
Use getBounds() or getBounds2D() to get the width/height of the bounding box required to hold this Polygon when rendered out into a rectangle. (e.g. boundingBox)
Create a new BufferedImage with these width/height values.
Get the Graphics2D from the new BufferedImage (e.g. newG2)
newG2.drawImage(originalImage, boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height)
NOTE This is where my memory is failing me; at some point you need to set the clip on newG2 (newG2.setClip(someShape)) so when the bounding box is rendered into it, you don't get the full bounding box of graphics rendered in, but instead some subset as defined by the yellow outline.
One easy way to do this is to create two Polygon's:
poly1 = a java.awt.Polygon that defines the yellow selection in the ORIGINAL image.
poly2 = a java.awt.Polygon that defines the exact same shape of Polygon, but shifted to a 0,0 origin point.
poly1 is used to get the bounding box to copy out the full bounding box that encompasses the content selected in yellow (and extra content around it)
poly2 is used to set the clip on the target Graphics2D (newG2) so when the bounding box is rendered into it, we clip back out everything outside of that Yellow shape so we just get the content in Yellow. You'll likely want to use an ARGB image type and set the background of the target image as transparent otherwise you'll get a black fill color.
I think this is the right direction for the clips; I was up to my eyeballs in Java2D for years and years but have been out of it for a while and forget if this will give you exactly what you want or not; you might need to tweak it around, but these are all the tools you need.
I am new to android, and my group is currently creating a graphing application using a GlSurfaceView using opengl es 2.0.
We have recently displayed the grid and tickmarks on the plot and now I have been assigned the task to implement a numeric scale and labeling the x and y axis as "X" and "Y".
After doing a lot of research I have determined to accomplish this by rendering a string of characters to a bitmap. I have encountered many problems in achieving this. I understand the basic concept. I know I will need the alphanumeric characters "0123456789" and "XY"and"-"(for the -x and -y scale). I have seen many different examples and have tried extensively to follow JVitella's example here here
I am beginning to grasp the concept but as far as the my string goes I know I have 13 characters so how large should my bitmap be?
Also in Jvitelas example I am dumbfounded by the code:
Drawable background = context.getResources().getDrawable(R.drawable.background);
I dont understand what exactly is going on and when I code this I recieve a syntax error on context.
For my application I understand I would need to save the string into a bit map much like this. I would create a bitmap but how big should it be? Then I create a canvas from the bitmap and canvas.drawText into the bitmap.
[ 0 1 2 3 4 ]
| 5 6 7 8 9 |
[ X Y Z ]
Basically I am asking:
How to achieve the following bit map above?
How would I draw single digit numbers from the bit map?
How would I draw numbers with more than one digit?
You're asking a lot of questions, but I'll try to answer a few:
so how large should my bitmap be?
It's really up to you, depending on how crisp you want the text to be. You could allocate a huge bitmap with hundreds of pixels for each character that would zoom very well, or a very small bitmap with limited resolution. I'd say whatever "font size" you want to have, allocate at least that many pixels in height for each character. So if you want to draw something with a font size of "20", then maybe you need a bitmap 5x20 by 3x20 or 100x60.
How would I draw single digit numbers from the bit map?
You'll draw a quad with opengl in the place where you want to draw a letter, and you use the texture coordinates of that quad to pick a letter.
For example if I want to draw an X, then you draw a quad on the screen, and assign it's texcoords from (0,0) to (0.2, 0.33), which selects the left 1/5th of the texture, and the bottom 1/3rd of the texture. You'll see how a box like this lines up with the position of the "X" in your texture.
How would I draw numbers with more than one digit?
You just draw two independent single digits right next to each other.
If your only goal here is to draw text in Android, it might be easier to just use a FrameLayout, and layer TextViews overtop of your GLSurfaceView. OpenGL isn't designed for text which makes it somewhat cumbersome.