为什么 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)

如有任何帮助,我们将不胜感激,

干杯

gimageGraphics 都是创建两次的相同图形,这可能有一些影响(不太确定)...

您还在绘制完成之前将可变图像设置为样式的背景。我不知道这是否是您所看到的异常现象的原因,但我怀疑是该代码。

受到 的启发,我终于使用另一个中间图像使其工作,仅在 (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);