为什么 drawString 方法似乎并不总是从给定的坐标开始?
Why drawString method does not seem to always start at the given coordinates?
在我的代码中,我无法在精确坐标处绘制字符串。它的左上角不是从给定的坐标开始,而是从其他地方开始。但是,如果我从相同的给定坐标绘制一个矩形,则它放置得很好。这种行为到底怎么可能?
这是我在 beforeShow() 方法中调用的代码:
Image photoBase = fetchResourceFile().getImage("Voiture_4_3.jpg");
Image watermark = fetchResourceFile().getImage("Watermark.png");
f.setLayout(new LayeredLayout());
final Label drawing = new Label();
f.addComponent(drawing);
// Image mutable dans laquelle on va dessiner (fond blancpar défaut)
Image mutableImage = Image.createImage(photoBase.getWidth(), photoBase.getHeight());
// Paint all the stuff
paintAll(mutableImage.getGraphics(), photoBase, watermark, photoBase.getWidth(), photoBase.getHeight());
drawing.getUnselectedStyle().setBgImage(mutableImage);
drawing.getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
// Save the graphics
// Save the image with the ImageIO class
long time = new Date().getTime();
OutputStream os;
try {
os = Storage.getInstance().createOutputStream("screenshot_" + Long.toString(time) + ".png");
ImageIO.getImageIO().save(mutableImage, os, ImageIO.FORMAT_PNG, 1.0f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
以及 paintAll 方法
public void paintAll(Graphics g, Image background, Image watermark, int width, int height) {
// Full quality
float saveQuality = 1.0f;
// Create image as buffer
Image imageBuffer = Image.createImage(width, height, 0xffffff);
// Create graphics out of image object
Graphics imageGraphics = imageBuffer.getGraphics();
// Do your drawing operations on the graphics from the image
imageGraphics.drawImage(background, 0, 0);
imageGraphics.drawImage(watermark, 0, 0);
imageGraphics.setColor(0xFF0000);
// Upper left corner
imageGraphics.fillRect(0, 0, 10, 10);
// Lower right corner
imageGraphics.setColor(0x00FF00);
imageGraphics.fillRect(width - 10, height - 10, 10, 10);
imageGraphics.setColor(0xFF0000);
Font f = Font.createTrueTypeFont("Geometos", "Geometos.ttf").derive(220, Font.STYLE_BOLD);
imageGraphics.setFont(f);
// Draw a string right below the M from Mercedes on the car windscreen (measured in Gimp)
int w = 0, h = 0;
imageGraphics.drawString("HelloWorld", w, h);
// Coin haut droit de la string
imageGraphics.setColor(0x0000FF);
imageGraphics.fillRect(w, h, 20, 20);
// Draw the complete image on your Graphics object g (the screen I guess)
g.drawImage(imageBuffer, 0, 0);
}
w = 0、h = 0(无明显偏移)的结果:
w = 841、h = 610 的结果(偏移出现在两个轴上:挡风玻璃上 Mercedes M 附近的蓝点与 Hello World 字符串之间存在偏移)
编辑1:
我还阅读了此 SO question for Android,建议将 dpi 转换为像素。它也适用于代号一吗?如果是这样,我该怎么做?我试过了
Display.getInstance().convertToPixel(measureInMillimeterFromGimp)
没有成功(我使用 mm 因为 javadoc 告诉 dpi 大约是 1 mm)
如有任何帮助,我们将不胜感激,
干杯
g
和 imageGraphics
都是创建两次的相同图形,这可能有一些影响(不太确定)...
您还在绘制完成之前将可变图像设置为样式的背景。我不知道这是否是您所看到的异常现象的原因,但我怀疑是该代码。
受到 的启发,我终于使用另一个中间图像使其工作,仅在 (0 ; 0) 处写入字符串,然后在正确坐标的 imageBuffer 图像上绘制此图像。它有效,但在我看来 drawString(Image, Coordinates) 应该直接在给定坐标处绘制,不是吗@Shai?
这是我用来解决问题的方法 paintAll(beforeShow 代码没有改变):
// Full quality
float saveQuality = 1.0f;
String mess = "HelloWorld";
// Create image as buffer
Image imageBuffer = Image.createImage(width, height, 0xffffff);
// Create graphics out of image object
Graphics imageGraphics = imageBuffer.getGraphics();
// Do your drawing operations on the graphics from the image
imageGraphics.drawImage(background, 0, 0);
imageGraphics.drawImage(watermark, 0, 0);
imageGraphics.setColor(0xFF0000);
// Upper left corner
imageGraphics.fillRect(0, 0, 10, 10);
// Lower right corner
imageGraphics.setColor(0x00FF00);
imageGraphics.fillRect(width - 10, height - 10, 10, 10);
// Create an intermediate image just with the message string (will be moved to the right coordinates later)
Font f = Font.createTrueTypeFont("Geometos", "Geometos.ttf").derive(150, Font.STYLE_BOLD);
// Get the message dimensions
int messWidth = f.stringWidth(mess);
int messHeight = f.getHeight();
Image messageImageBuffer = Image.createImage(messWidth, messHeight, 0xffffff);
Graphics messageImageGraphics = messageImageBuffer.getGraphics();
messageImageGraphics.setColor(0xFF0000);
messageImageGraphics.setFont(f);
// Write the string at (0; 0)
messageImageGraphics.drawString(mess, 0, 0);
// Move the string to its final location right below the M from Mercedes on the car windscreen (measured in Gimp)
int w = 841, h = 610;
imageGraphics.drawImage(messageImageBuffer, w, h);
// This "point" is expected to be on the lower left corner of the M letter from Mercedes and on the upper left corner of the message string
imageGraphics.setColor(0x0000FF);
imageGraphics.fillRect(w, h, 20, 20);
// Draw the complete image on your Graphics object g
g.drawImage(imageBuffer, 0, 0);
在我的代码中,我无法在精确坐标处绘制字符串。它的左上角不是从给定的坐标开始,而是从其他地方开始。但是,如果我从相同的给定坐标绘制一个矩形,则它放置得很好。这种行为到底怎么可能?
这是我在 beforeShow() 方法中调用的代码:
Image photoBase = fetchResourceFile().getImage("Voiture_4_3.jpg");
Image watermark = fetchResourceFile().getImage("Watermark.png");
f.setLayout(new LayeredLayout());
final Label drawing = new Label();
f.addComponent(drawing);
// Image mutable dans laquelle on va dessiner (fond blancpar défaut)
Image mutableImage = Image.createImage(photoBase.getWidth(), photoBase.getHeight());
// Paint all the stuff
paintAll(mutableImage.getGraphics(), photoBase, watermark, photoBase.getWidth(), photoBase.getHeight());
drawing.getUnselectedStyle().setBgImage(mutableImage);
drawing.getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
// Save the graphics
// Save the image with the ImageIO class
long time = new Date().getTime();
OutputStream os;
try {
os = Storage.getInstance().createOutputStream("screenshot_" + Long.toString(time) + ".png");
ImageIO.getImageIO().save(mutableImage, os, ImageIO.FORMAT_PNG, 1.0f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
以及 paintAll 方法
public void paintAll(Graphics g, Image background, Image watermark, int width, int height) {
// Full quality
float saveQuality = 1.0f;
// Create image as buffer
Image imageBuffer = Image.createImage(width, height, 0xffffff);
// Create graphics out of image object
Graphics imageGraphics = imageBuffer.getGraphics();
// Do your drawing operations on the graphics from the image
imageGraphics.drawImage(background, 0, 0);
imageGraphics.drawImage(watermark, 0, 0);
imageGraphics.setColor(0xFF0000);
// Upper left corner
imageGraphics.fillRect(0, 0, 10, 10);
// Lower right corner
imageGraphics.setColor(0x00FF00);
imageGraphics.fillRect(width - 10, height - 10, 10, 10);
imageGraphics.setColor(0xFF0000);
Font f = Font.createTrueTypeFont("Geometos", "Geometos.ttf").derive(220, Font.STYLE_BOLD);
imageGraphics.setFont(f);
// Draw a string right below the M from Mercedes on the car windscreen (measured in Gimp)
int w = 0, h = 0;
imageGraphics.drawString("HelloWorld", w, h);
// Coin haut droit de la string
imageGraphics.setColor(0x0000FF);
imageGraphics.fillRect(w, h, 20, 20);
// Draw the complete image on your Graphics object g (the screen I guess)
g.drawImage(imageBuffer, 0, 0);
}
w = 0、h = 0(无明显偏移)的结果:
w = 841、h = 610 的结果(偏移出现在两个轴上:挡风玻璃上 Mercedes M 附近的蓝点与 Hello World 字符串之间存在偏移)
编辑1: 我还阅读了此 SO question for Android,建议将 dpi 转换为像素。它也适用于代号一吗?如果是这样,我该怎么做?我试过了
Display.getInstance().convertToPixel(measureInMillimeterFromGimp)
没有成功(我使用 mm 因为 javadoc 告诉 dpi 大约是 1 mm)
如有任何帮助,我们将不胜感激,
干杯
g
和 imageGraphics
都是创建两次的相同图形,这可能有一些影响(不太确定)...
您还在绘制完成之前将可变图像设置为样式的背景。我不知道这是否是您所看到的异常现象的原因,但我怀疑是该代码。
受到
这是我用来解决问题的方法 paintAll(beforeShow 代码没有改变):
// Full quality
float saveQuality = 1.0f;
String mess = "HelloWorld";
// Create image as buffer
Image imageBuffer = Image.createImage(width, height, 0xffffff);
// Create graphics out of image object
Graphics imageGraphics = imageBuffer.getGraphics();
// Do your drawing operations on the graphics from the image
imageGraphics.drawImage(background, 0, 0);
imageGraphics.drawImage(watermark, 0, 0);
imageGraphics.setColor(0xFF0000);
// Upper left corner
imageGraphics.fillRect(0, 0, 10, 10);
// Lower right corner
imageGraphics.setColor(0x00FF00);
imageGraphics.fillRect(width - 10, height - 10, 10, 10);
// Create an intermediate image just with the message string (will be moved to the right coordinates later)
Font f = Font.createTrueTypeFont("Geometos", "Geometos.ttf").derive(150, Font.STYLE_BOLD);
// Get the message dimensions
int messWidth = f.stringWidth(mess);
int messHeight = f.getHeight();
Image messageImageBuffer = Image.createImage(messWidth, messHeight, 0xffffff);
Graphics messageImageGraphics = messageImageBuffer.getGraphics();
messageImageGraphics.setColor(0xFF0000);
messageImageGraphics.setFont(f);
// Write the string at (0; 0)
messageImageGraphics.drawString(mess, 0, 0);
// Move the string to its final location right below the M from Mercedes on the car windscreen (measured in Gimp)
int w = 841, h = 610;
imageGraphics.drawImage(messageImageBuffer, w, h);
// This "point" is expected to be on the lower left corner of the M letter from Mercedes and on the upper left corner of the message string
imageGraphics.setColor(0x0000FF);
imageGraphics.fillRect(w, h, 20, 20);
// Draw the complete image on your Graphics object g
g.drawImage(imageBuffer, 0, 0);