2016-06-13 8 views
1

В моем коде я не могу нарисовать строку с точными координатами. Его верхний левый угол не начинается с заданных координат, а где-то еще. Однако, если я рисую прямоугольник из тех же заданных координат, он хорошо расположен. Как это возможно?Почему метод drawString не всегда начинается с заданных координат?

Вот мой код, который я называю в методе 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); 


} 

Результат для ш = 0, ч = 0 (без видимых компенсировали): no offset

Результат для w = 841, h = 610 (смещение появляется на обеих сторонах: имеется смещение между голубой точкой вблизи Mercedes M на ветровом стекле и Hello World String) with offset

EDIT1: Я также прочитал это SO question для Android, где рекомендуется преобразовать точек на дюйм в пикселе. Это также относится к Codename One? Если да, то как я могу это сделать? Я попытался

Display.getInstance().convertToPixel(measureInMillimeterFromGimp) 

без успеха (я использовал мм, потому что Javadoc говорит, что точек на дюйм составляет около 1 мм)

Любая помощь будет оценена,

Приветствия

ответ

0

Вдохновленный от Gabriel Hass' answer Я, наконец, сделал это, используя другое промежуточное изображение, чтобы написать только строку String at (0; 0), а затем нарисовать это изображение на изображении ImageBuffer теперь в правильных координатах. Это работает, но на мой взгляд drawString (Image, Coordinates) должен непосредственно рисовать по заданным координатам, не так ли @Shai?

String eventually at the righ coordinates (blue point expected to be on the top left corner of String HelloWorld

Вот метод 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); 
+0

Похоже, что это обходное решение больше не понадобится из версии CN1 lib версии 115 и далее (см. http://stackoverflow.com/questions/37986722/why- do-i-get-a-different-behviour-in-codename-one-simulator-than-on-a-real-andro для деталей). Это действительно был симулятор! – HelloWorld

1

Оба g и imageGraphics являются одна и та же графика, созданная дважды, что может иметь некоторые последствия (не совсем уверен) ...

Вы также устанавливаете mutab le image на фоне стиля, прежде чем вы закончите рисовать его. Я не знаю, будет ли это причиной для странностей, которые вы видите, но я бы заподозрил этот код.

+0

imageGraphics трюк, чтобы сохранить изображение в полном разрешении (см Http: //stackoverflow.com/a/37748864/6351897). Я изменю подозрительную часть, которую вы указали! – HelloWorld

+0

Несчастливо устанавливая изменчивое изображение на задний план после рисования, ничего не меняет (хотя это имеет смысл). Спасибо, в любом случае. Я до сих пор не могу понять, почему синий рекатангл следует за координатами, но строка не работает! – HelloWorld

+0

Являются ли эти скриншоты из масштабированного режима в симуляторе или с устройств? Обратите внимание, что некоторые артефакты могут возникать, если «прокручиваемый» не установлен в меню симулятора. –