2015-07-13 112 views
2

我試圖在圖像的頂部和底部實現動態文本。以下是我現在能夠製作的輸出,但底線中的字符彼此重疊。請告訴我在哪裏,我在我的代碼出了問題:Graphics.drawString重疊前一個字符

enter image description here

代碼段運行時要產生圖像的圖像:

package com.logogenerator.util; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.NoninvertibleTransformException; 
import java.awt.geom.Point2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import javax.imageio.ImageIO; 

public class CurvedText { 

    public static void main(String[] args) throws NoninvertibleTransformException { 
     try { 

      final BufferedImage image = ImageIO.read(new File("E://xxx.png")); 
      Graphics2D g; 
      g = (Graphics2D) image.getGraphics(); 
      Font font = new Font("Serif", Font.PLAIN, 16); 
      g.setFont(font); 
      g.setColor(Color.GREEN); 

      drawCircleTextTop("ABCDEFGH", image, g); 
      drawCircleTextBottom("ABCDEFGH", image, g); 

      g.dispose(); 
      ImageIO.write(image, "png", new File("E://Boathouse-WorkSpace//testboth.png")); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Flip Down and writing the text 
    * @param s String to be written on the image 
    * @param image Buffered image on which string to be written 
    * @param g Graphics 2D object to access the Buffered Image 
    * @throws IOException 
    * @throws NoninvertibleTransformException 
    */ 
    private static void drawCircleTextTop(String s, BufferedImage image, Graphics2D g) throws IOException, NoninvertibleTransformException { 

     if(image != null){ 

      Dimension cd = new Dimension(256,256); 
      Point pt = new Point(cd.width/2, cd.height/2); 
      int radius = 100; 


      String st = s; 
      Point center = pt; 
      double r = radius; 
      double charDegree = 5; 
      double a1 = Math.toRadians(360 - (s.length()/2 * charDegree));//-Math.PI/4; 
      double af = 1.0; 


      double curangle = a1; 
      Point2D c = new Point2D.Double(center.x, center.y); 
      char ch[] = st.toCharArray(); 
      FontMetrics fm = g.getFontMetrics(); 
      AffineTransform xform1, cxform; 
      xform1 = AffineTransform.getTranslateInstance(c.getX(),c.getY()); 
      for(int i = 0; i < ch.length; i++) { 
       double cwid = (double)(getWidth(ch[i],fm)); 
       if (!(ch[i] == ' ' || Character.isSpaceChar(ch[i]))) { 
        cwid = (double)(fm.charWidth(ch[i])); 
        cxform = new AffineTransform(xform1); 
        cxform.rotate(curangle, 0.0, 0.0); 
        String chstr = new String(ch, i, 1); 
        g.setTransform(cxform); 
        g.drawString(chstr, (float)(-cwid/2), (float)(-r)); 
       } 

       // compute advance of angle assuming cwid< 
       if (i < (ch.length - 1)) { 
        double adv = cwid/2.0 + fm.getLeading() + getWidth(ch[i + 1],fm)/2.0; 
        curangle += Math.sin(adv/r); 
       } 
      } 

     } 
    } 

    /** 
    * Flip Down and writing the text 
    * @param s String to be written on the image 
    * @param image Buffered image on which string to be written 
    * @param g Graphics 2D object to access the Buffered Image 
    * @throws IOException 
    * @throws NoninvertibleTransformException 
    */ 
    private static void drawCircleTextBottom(String s, BufferedImage image, Graphics2D g) throws IOException, NoninvertibleTransformException { 

     if(image != null){ 

      Dimension cd = new Dimension(256,256); 
      Point pt = new Point(cd.width/2, cd.height/2); 
      int radius = 100; 

      String st = s; 
      Point center = pt; 
      double r = radius; 
      double charDegree = 4; 
      double a1 = Math.toRadians(360 - (s.length()/2 * charDegree));//-Math.PI/4; 
      double af = 1.0; 



      double curangle = a1; 
      Point2D c = new Point2D.Double(center.x, center.y); 
      char ch[] = st.toCharArray(); 
      FontMetrics fm = g.getFontMetrics(); 
      AffineTransform xform1, cxform; 
      xform1 = AffineTransform.getTranslateInstance(c.getX(),c.getY()); 
//   for(int i = ch.length-1; i > -1; i--) { 
      for(int i = ch.length-1; i >-1; i--) { 
       double cwid = (double)(getWidth(ch[i],fm)); 
       if (!(ch[i] == ' ' || Character.isSpaceChar(ch[i]))) { 
        cwid = (double)(fm.charWidth(ch[i])); 
        cxform = new AffineTransform(xform1); 
        cxform.rotate(curangle, 0.0, 0.0); 
        String chstr = new String(ch, i, 1); 
        g.setTransform(cxform); 
        g.drawString(chstr, (float)(cwid/2), (float)(r)); 
//     System.out.println("Curve Angle :"+curangle); 
//     System.out.println("Cwid : "+cwid); 
       } 

       // compute advance of angle assuming cwid< 
       if (i < (ch.length - 1)) { 
        double adv = cwid/2.0 + fm.getLeading() + getWidth(ch[i + 1],fm)/2.0; 
        curangle += Math.sin((adv/r)); 
       } 
      } 

     } 
    } 

    static int getWidth(char c, FontMetrics fm) { 
     if (c == ' ' || Character.isSpaceChar(c)) { 
      return fm.charWidth('n'); 
     } 
      else { 
      return fm.charWidth(c); 
     } 
    } 
} 

這有什麼錯在我的做法?

+0

我正在通過在字符串的最後加入一些額外的空格來解決這個問題,然後它的工作正常。但似乎並不是解決方案,這種方法存在一些問題。 – Dipak

+0

'final BufferedImage image = ImageIO.read(new File(「E://xxx.png」));'1)爲了更快提供更好的幫助,請發佈[MCVE](http://stackoverflow.com/help/mcve )(最小完整可驗證示例)或[SSCCE](http://www.sscce.org/)(簡短,獨立,正確的示例)。 2)獲取圖像的一種方法是通過[本問答](http://stackoverflow.com/q/19209650/418556)中的圖像進行熱鏈接。 –

回答

1

答案可以通過在中心圍繞與字母相同的radius繪製一個圓來找到。

enter image description here

該角度被選擇,以字母在給定的半徑分離。但是當他們被吸引到之外頂部的圓圈(在信件的頂部增加了額外的空間)時,他們在的底部繪製了圓圈(去除了信件頂部的空間 - 將它們擠在一起)。

相關問題