i have to insert image with drawImage(page, docu, x, y, ximage, fRatioImage), until now I can insert the image with this function, but the problem is that the image is shifted relative to the x and y coordinates.
does anyone knows the unit of measurement used by this function to the point (x, y)?
this is the code that i use :
PDDocument docu=docu = PDDocument.load(filedoc);
inputStream in = ImageSignature.is;
biimage=ImageIO.read(in);
PDPage page = (PDPage)docu.getDocumentCatalog().getAllPages().get( 0 );
PDXObjectImage ximage = new PDJpeg(docu, biimage );
PdfBoxImageUtil.drawImage(page, docu, x, y, ximage, fRatioImage);
Related
I'm trying to create a PDF that's PAC3 approved for accessibility but I'm having an issue when it comes to the links I'm writing. This is the code I have one function that draws the text and tags it given the structType (this function is from https://github.com/chris271/UAPDFBox/blob/a8b280bcbc838722ba872d6b382b8fd45bd35303/src/com/wi/test/util/PDFormBuilder.java)
public PDStructureElement drawElement(Cell textCell, float x, float y, float height,PDStructureElement parent,
String structType, int pageIndex) throws IOException {
//Set up the next marked content element with an MCID and create the containing H1 structure element.
PDPageContentStream contents = new PDPageContentStream(pdf, pages.get(pageIndex),
PDPageContentStream.AppendMode.APPEND, false);
currentElem = addContentToParent(null, structType, parent);
setNextMarkedContentDictionary();
contents.beginMarkedContent(COSName.ARTIFACT, PDPropertyList.create(currentMarkedContentDictionary));
//Draws the cell itself with the given colors and location.
drawDataCell(textCell, x, y + height, height * 2, contents);
contents.endMarkedContent();
addContentToParent(COSName.ARTIFACT, null, currentElem);
contents.close();
//Set up the next marked content element with an MCID and create the containing P structure element.
contents = new PDPageContentStream(pdf, pages.get(pageIndex), PDPageContentStream.AppendMode.APPEND, false);
setNextMarkedContentDictionary();
contents.beginMarkedContent(COSName.P, PDPropertyList.create(currentMarkedContentDictionary));
//Draws the given text centered within the current table cell.
drawCellText(textCell, x, y + height + textCell.getFontSize(), contents, pages.get(pageIndex).getResources());
//End the marked content and append it's P structure element to the containing P structure element.
contents.endMarkedContent();
addContentToParent(COSName.P, null, currentElem);
contents.close();
return currentElem;
}
After it's written to the page I call a separate function to add the underline for hyperlinks
public void drawLink(float firstX,float firstY,float lastX,float width, float height,int pageNum, float lastCharWidth) throws IOException {
PDAnnotationTextMarkup markup = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_UNDERLINE);
PDRectangle position = new PDRectangle();
position.setLowerLeftX(firstX);
position.setLowerLeftY(firstY);
position.setUpperRightX(firstX + width);
position.setUpperRightY(firstY + height);
markup.setRectangle(position);
//need to modify quadpoints lastX so it's inline with link
float quadPoints[] = {firstX, firstY + height + 2,
lastX + lastCharWidth, firstY + height + 2,
firstX, firstY - 5,
lastX + lastCharWidth, firstY - 5};
markup.setQuadPoints(quadPoints);
PDColor color = new PDColor(new float[]{ 1, 15/ 255F, 1 }, PDDeviceRGB.INSTANCE);
markup.setColor(color);
pdf.getPage(pageNum).getAnnotations().add(markup);
}
The result of calling these 2 functions are below, it draws the link properly but I'm missing information for the annotation. My question is how do I utilize the PDAnnotation object to create a PAC3 approved annotation?
Image of PAC3 detailed results
I'm using geotools to develop a wms service. I create a map layer and add it into MapContent. Then I develop a GetMap service. I display the map on the browser successfully, but the map location is always wrong. Like this:
And the request parameters are:
SERVICE: WMS
VERSION: 1.1.0
REQUEST: GetMap
FORMAT: image/png
TRANSPARENT: true
LAYERS: layer
SRS: EPSG:4326
STYLES:
WIDTH: 997
HEIGHT: 499
BBOX: 63.2958984375,3.1494140625,150.9228515625,47.0068359375
The response preview is like:
I want to display the points at the right location.
Here is my code to deal with GetMap request:
double x1, y1, x2, y2;
String[] BBOX = request.getParameter("BBOX").split(",");
x1 = Double.parseDouble(BBOX[0]);
y1 = Double.parseDouble(BBOX[1]);
x2 = Double.parseDouble(BBOX[2]);
y2 = Double.parseDouble(BBOX[3]);
int width = Integer.parseInt(request.getParameter("WIDTH")),
height = Integer.parseInt(request.getParameter("HEIGHT"));
CoordinateReferenceSystem crs = CRS.decode(request.getParameter("SRS"));
ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, y1, x2, y2, crs);//I think some wrong here,but I try to modify many times,it is not work
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
WMSRequest wmsRequest = new WMSRequest();
wmsRequest.getGetMap();
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = bi.getGraphics();
Rectangle rectangle = new Rectangle(0, 0, width, height);
MapViewport mv = new MapViewport();
mv.setBounds(mapArea);
mv.setCoordinateReferenceSystem(crs);
mv.setScreenArea(rectangle);
mapContent.setViewport(mv);
//AffineTransform atf = geometryManage.getRenderingTransform(width, height, mv.getBounds());
StreamingRenderer sr = new StreamingRenderer();
sr.setMapContent(mapContent);
sr.paint((Graphics2D) graphics, rectangle, mapArea);
ImageIO.write(bi, "png", out);
out.close();
I solve it.
The wrong is here :
ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, y1, x2, y2, crs);
I use this statement to select the display area of map.But the order of parameter is wrong.
BBOX from request has 4 parameter,the order is [longitude,latitude,longitude,latitude] ,and in the CRS WGS 84 the longitude is define to y,latitude is define to x.
But the ReferencedEnvelope Constructor is :
ReferencedEnvelope(double x1, double x2, double y1, double y2, CoordinateReferenceSystem crs)
More detail of ReferencedEnvelope:Document of ReferencedEnvelope
So I change the code:
double x1, y1, x2, y2;
y1 = Double.parseDouble(BBOX[0]);
x1 = Double.parseDouble(BBOX[1]);
y2 = Double.parseDouble(BBOX[2]);
x2 = Double.parseDouble(BBOX[3]);
ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, x2, y1, y2, crs);
Then it is ok.
Different coordinate systems have different coordinate sequences,we can view it by printing its text message,such as
GEOGCS["WGS84(DD)",
DATUM["WGS84",
SPHEROID["WGS84", 6378137.0, 298.257223563]],
PRIMEM["Greenwich", 0.0],
UNIT["degree", 0.017453292519943295],
AXIS["Geodetic longitude", EAST],
AXIS["Geodetic latitude", NORTH]]
define the longitude first, and
GEOGCS["WGS 84",
DATUM["World Geodetic System 1984",
SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],
UNIT["degree", 0.017453292519943295],
AXIS["Geodetic latitude", NORTH],
AXIS["Geodetic longitude", EAST],
AUTHORITY["EPSG","4326"]]
define the latitude first
I have a PDF viewer that doesn't show highlights if they do not have an appearance stream. I'm trying out iText 7 core in java to try and add highlight annotations to PDFs but these annotations do not have appearance streams, and thus I'm looking to try and add them myself when writing the annotations to the PDF file.
I've come across this old answer, but it's for C# and iText 5, and I can't seem to figure out how to replicate it in iText 7 with a successful result.
So my question is thus: how do you set appearance streams on the highlighting annotations in iText 7 core that are working?
The furthest I've gotten with the code is shown below. I'm using the RegexBasedLocationExtrationStrategy class to find the locations of all search words in the pdf.
RegexBasedLocationExtractionStrategy evntlstnr = new RegexBasedLocationExtractionStrategy(pattern);
for (int pIdx = 0; pIdx < pdfDoc.getNumberOfPages(); ++pIdx) {
final PdfPage page = pdfDoc.getPage(pIdx + 1);
new PdfCanvasProcessor(evntlstnr).processPageContent(page);
Collection<IPdfTextLocation> locations = evntlstnr.getResultantLocations();
for (IPdfTextLocation location : locations) {
Rectangle rect = location.getRectangle();
// Specify quad points in Z-like order
// [0,1] x1,y1 [2,3] x2,y2
// [4,5] x3,y3 [6,7] x4,y4
float[] quads = new float[8];
quads[0] = rect.getX();
quads[1] = rect.getY() + rect.getHeight();
quads[2] = rect.getX() + rect.getWidth();
quads[3] = quads[1];
quads[4] = quads[0];
quads[5] = rect.getY();
quads[6] = quads[2];
quads[7] = quads[5];
Color highlightColor = new DeviceRgb(0f, 0f, 1f);
PdfTextMarkupAnnotation highlight = PdfTextMarkupAnnotation.createHighLight(rect, quads);
highlight.setColor(highlightColor);
Rectangle appearRect = new Rectangle(0f, 0f, rect.getWidth(), rect.getHeight());
PdfFormXObject appearObj = new PdfFormXObject(appearRect);
final PdfResources appearRes = appearObj.getResources();
PdfExtGState extGState = new PdfExtGState();
extGState.setBlendMode(PdfExtGState.BM_MULTIPLY);
appearRes.addExtGState(extGState);
appearObj.setBBox(new PdfArray(new float[] {0f, 0f, rect.getWidth(), rect.getHeight()}));
PdfShading appearShading = new PdfShading.Axial(highlightColor.getColorSpace(), 0f, 0f, highlightColor.getColorValue(), 1f, 1f, highlightColor.getColorValue());
appearRes.addShading(appearShading);
appearRes.addColorSpace(highlightColor.getColorSpace());
PdfAnnotationAppearance appearance = new PdfAnnotationAppearance(appearObj.getPdfObject());
highlight.setNormalAppearance(appearance);
highlight.setFlag(PdfAnnotation.PRINT);
page.addAnnotation(highlight);
}
}
Using Samuel's answer I stumbled my way to a working answer.
I'm no expect in the PDF standard and this framework (iText), but my hypothesis, based on my working example below, is that the rectangle I was trying to write for the highlight is a crude fall-back method for "faking" the highlight rectangle when the viewer cannot render the annotations (since they have no appearance stream). Realizing this that the two operations are not linked, I came to the working example shown below. Hope this helps others in the future.
RegexBasedLocationExtractionStrategy evntlstnr = new RegexBasedLocationExtractionStrategy(pattern);
for (int pIdx = 0; pIdx < pdfDoc.getNumberOfPages(); ++pIdx) {
final PdfPage page = pdfDoc.getPage(pIdx + 1);
new PdfCanvasProcessor(evntlstnr).processPageContent(page);
Collection<IPdfTextLocation> locations = evntlstnr.getResultantLocations();
for (IPdfTextLocation location : locations) {
Rectangle rect = location.getRectangle();
// Specify quad points in Z-like order
// [0,1] x1,y1 [2,3] x2,y2
// [4,5] x3,y3 [6,7] x4,y4
float[] quads = new float[8];
quads[0] = rect.getX();
quads[1] = rect.getY() + rect.getHeight();
quads[2] = rect.getX() + rect.getWidth();
quads[3] = quads[1];
quads[4] = quads[0];
quads[5] = rect.getY();
quads[6] = quads[2];
quads[7] = quads[5];
Color highlightColor = new DeviceRgb(1f, 1f, 0f);
PdfTextMarkupAnnotation highlight = PdfTextMarkupAnnotation.createHighLight(rect, quads);
highlight.setColor(highlightColor);
highlight.setFlag(PdfAnnotation.PRINT);
page.addAnnotation(highlight);
PdfCanvas canvas = new PdfCanvas(page);
PdfExtGState extGState = new PdfExtGState();
extGState.setBlendMode(PdfExtGState.BM_MULTIPLY);
canvas.setExtGState(extGState);
canvas.rectangle(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
canvas.setFillColor(highlightColor);
canvas.fill();
canvas.release();
}
}
I'm pretty much a beginner when it comes to game development, especially with Libgdx, so far I made it so I can load any .tmx map or save it, I'm probably going to try and see how procedurally generating terrains works but right now I'm getting this weird error when I delete a block (that block consists of a TiledMapTile and a box2d body), I'm deletting it and after the deletion I'm creating a smaller entity that will also be a body, that represents the block I just deleted, as a drop for the player, this is the error I'm getting when I click a block, it only happens after the first block is deleted, so, one block is deleted and a small entity is created, but if I try to do it a second time, the game breaks and this appears:
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffb8ecd9f58, pid=6580, tid=0x0000000000002474
JRE version: Java(TM) SE Runtime Environment (8.0_121-b13) (build 1.8.0_121-b13)
Java VM: Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode windows-amd64 compressed oops)
Problematic frame:
C [ntdll.dll+0x39f58]
Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
An error report file with more information is saved as:
C:\Libgdx Projects Fedora\WINDOWS\Generator Test\core\assets\hs_err_pid6580.log
If you would like to submit a bug report, please visit:
http://bugreport.java.com/bugreport/crash.jsp
The crash happened outside the Java Virtual Machine in native code.
See problematic frame for where to report the bug.
[error occurred during error reporting , id 0xc0000005]
This is the error log:
http://pastebin.com/a8iUH8Rz
This is where I delete the blocks:
public void destroyTerrain( ArrayList<Block> terrain, ArrayList<BlockDrop> blockDropsList ) {
int x = Gdx.input.getX() / 32;
int y = ( Gdx.graphics.getHeight() - Gdx.input.getY() ) / 32;
Iterator<Block> iterator = terrain.iterator();
while ( iterator.hasNext() ) {
Block block = iterator.next();
if ( x == ( int ) block.getBody().getPosition().x && y == ( int ) block.getBody().getPosition().y ) {
PolygonShape shape = ( PolygonShape ) block.getBody().getFixtureList().get( 0 ).getShape();
world.destroyBody( block.getBody() );
iterator.remove();
TiledMapTileLayer.Cell cell = ( ( TiledMapTileLayer ) map.getLayers().get( 0 ) ).getCell( x, y );
Texture tex = cell.getTile().getTextureRegion().getTexture();
// this is where the error is happening, when I'm creating a second blockDrop
BlockDrop blockDrop = new BlockDrop( screen, x, y, shape.getRadius() * 16, shape.getRadius() * 16 );
blockDrop.setTexture( tex );
blockDropsList.add( blockDrop );
cell.setTile( null );
}
}
}
This is the BlockDrop class:
public class BlockDrop extends Entity {
public BlockDrop( PlayGame screen, int x, int y, float width, float height ) {
super( screen );
posX = x;
posY = y;
type = BodyDef.BodyType.DynamicBody;
density = 0.2f;
friction = 0.4f;
shape = new PolygonShape();
( ( PolygonShape ) shape ).setAsBox( width, height, new Vector2( ( x / 32 ) + width * 2, ( y / 32 ) + height * 2 ), 0 );
createBody();
}
}
And this is the Entity:
abstract public class Entity {
private PlayGame screen;
float posX, posY;
private Body body;
Shape shape;
BodyDef.BodyType type;
float density;
float friction;
SpriteBatch batch;
Sprite sprite;
Entity( PlayGame screen ) {
this.screen = screen;
batch = new SpriteBatch();
sprite = new Sprite();
}
void createBody( ) {
BodyDef bodyDef = new BodyDef();
bodyDef.type = type;
bodyDef.position.set( posX, posY );
body = screen.getWorld().createBody( bodyDef );
body.setUserData( this );
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = density;
fixtureDef.friction = friction;
body.createFixture( fixtureDef );
dispose();
}
public void setTexture(Texture tex){
sprite.setTexture( tex );
}
public void render( ) {
sprite.setBounds( posX, posY, shape.getRadius(), shape.getRadius() );
batch.begin();
sprite.draw( batch );
batch.end();
}
public String toString( ) {
return getClass().getSimpleName();
}
public Body getBody( ) {
return body;
}
public void dispose( ) {
shape.dispose();
batch.dispose();
}
}
Any help would be greatly appreciated, it might just be a simple dumb thing and the code might be a mess right now, but I can't seem to get around this
This error usually happens when an object is being used after you disposed it.
You are using a shape that was disposed:
iterator.remove();
...
BlockDrop blockDrop = new BlockDrop( screen, x, y, shape.getRadius() * 16, shape.getRadius() * 16 );
It's better to create and remove physics body in separate loop.
Create List of item that you want to create and another list that you want to remove and also keep in mind that creation and deletion must be performed when physics World is unlocked.
private World physicsWorld;
if(!physicsWorld.isLocked()) {
removeBodyFromWorld();
addBodyIntoWorld();
}
In removeBodyFromWorld() method remove your desired entity and create new body in addBodyIntoWorld() method.
I am creating a car game and I want to rotate my car ( Image ) when I'm using the car but I don't know how. I've tried a few things that don't work. Here is what I have:
g2d.drawImage(DEFAULT_CAR_SKIN, DEFAULT_BOX.x, DEFAULT_BOX.y, null);
DEFAULT_BOX.setLocation(DEFAULT_BOX.x + 1, DEFAULT_BOX.y);
if (Game.rotateFront == true) {
AffineTransform identity = new AffineTransform();
AffineTransform trans = new AffineTransform();
trans.setTransform(identity);
trans.rotate(Math.toRadians(Game.Angle));
g2d.drawImage(DEFAULT_CAR_SKIN, trans, this);
}
But this code draws a new image but with the characteristics that I want.