I'm trying write some mechanism to creating mems. After the image is painted with text, the text quality is very low. I dont know what I'm doing wrong. Here is my following draw method:
private BufferedImage generateImage(File file) throws IOException {
Image image = ImageIO.read(file);
final int imgWidth = image.getWidth(null);
final int imgHeight = image.getHeight(null);
int labelHeight = (imgHeight / 2);
int labelWidth = (imgWidth - 25);
int xMargin = ((imgWidth - labelWidth) / 2);
int yMargin = (imgHeight - (labelHeight + 10));
Font font = new Font("Arial Black", Font.BOLD, 42);
String upperText = this.doggle.getUppertext().toUpperCase();
String bottomText = this.doggle.getBottomtext().toUpperCase();
ImagePanel background = new ImagePanel(image);
background.setSize(imgWidth, imgHeight);
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
String absoluteDiskPath = servletContext.getRealPath("/resources/images/logo.png");
BufferedImage imageLogo = ImageIO.read(new File(absoluteDiskPath));
ImageIcon icon = new ImageIcon(imageLogo);
JLabel imageLogoPanel = new JLabel ();
imageLogoPanel.setIcon(icon);
imageLogoPanel.setSize(imageLogo.getWidth(), imageLogo.getHeight());
imageLogoPanel.setVerticalAlignment(SwingConstants.BOTTOM);
JLabel textUpper = new JLabel();
textUpper.setText(upperText);
textUpper.setVerticalAlignment(SwingConstants.TOP);
textUpper.setSize(labelWidth, labelHeight);
textUpper.setPreferredSize(new Dimension(labelWidth, (imgHeight / 2)));
textUpper.setFont(font);
textUpper.setForeground(Color.decode("#" + this.doggle.getUppercolor()));
JLabel textUpperShadow = new JLabel(upperText, JLabel.CENTER);
textUpperShadow.setVerticalAlignment(SwingConstants.TOP);
textUpperShadow.setSize(labelWidth, labelHeight);
textUpperShadow.setPreferredSize(new Dimension(labelWidth, (imgHeight / 2)));
textUpperShadow.setFont(font);
textUpperShadow.setForeground(Color.BLACK);
JLabel textLower = new JLabel(bottomText, JLabel.CENTER);
textLower.setVerticalAlignment(SwingConstants.BOTTOM);
textLower.setSize(labelWidth, labelHeight);
textLower.setPreferredSize(new Dimension(labelWidth, (imgHeight / 2)));
textLower.setFont(font);
textLower.setForeground(Color.decode("#" + this.doggle.getBottomcolor()));
JLabel textLowerShadow = new JLabel(bottomText, JLabel.CENTER);
textLowerShadow.setVerticalAlignment(SwingConstants.BOTTOM);
textLowerShadow.setSize(labelWidth, labelHeight);
textLowerShadow.setPreferredSize(new Dimension(labelWidth, (imgHeight / 2)));
textLowerShadow.setFont(font);
textLowerShadow.setForeground(Color.BLACK);
background.add(textUpper);
background.add(textUpperShadow);
background.add(textLower);
background.add(textLowerShadow);
background.add(imageLogoPanel);
textUpper.setLocation(xMargin, 5);
textUpperShadow.setLocation((xMargin + 2), 7);
textLower.setLocation(xMargin, yMargin - 16);
textLowerShadow.setLocation((xMargin + 2), ((yMargin - 16) + 2));
imageLogoPanel.setLocation((xMargin - 5), ((yMargin * 2) - 8));
BufferedImage img = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
background.printAll(g2d);
g2d.dispose();
return img;
}
And here is a some part of the image (The text at the top is the actual text and bottom text is what it should look like)
What can I do to improve the visual quality of my text? I Will be grateful for help.
Related
In above code i want to use custom font (which is commented on code), when i use commented font1 then iam not getting output properly.
BufferedImage source = ImageIO.read(input_file);
File backImg = new File("C:\\Users\\saradhi\\Desktop\\water-lily-3784022__340.jpg");
BufferedImage backImgB = ImageIO.read(backImg);
final BufferedImage textImage = new BufferedImage(
backImgB.getWidth(),
backImgB.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = textImage.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
/*
* Font font1 = Font.createFont(Font.TRUETYPE_FONT, new
* File("C:\\Users\\saradhi\\Desktop\\Pacifico.ttf")); font1.deriveFont(9f);
*/
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 120);
GlyphVector gv = font.createGlyphVector(frc, name);
Rectangle2D box = gv.getVisualBounds();
int xOff = 25 + (int) - box.getX();
int yOff = 80 + (int) - box.getY();
Shape shape = gv.getOutline(xOff, yOff);
g.setClip(shape);
g.drawImage(backImgB, 0, 0, null);
g.setClip(null);
g.setStroke(new BasicStroke(2 f));
g.setColor(Color.BLACK);
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.draw(shape);
g.dispose();
File file = new File("cat-text.png");
ImageIO.write(textImage, "png", new File("C:\\Users\\saradhi\\Desktop\\resultEX.jpeg"));
i get the custom font through this code
Font font = Font.createFont(Font.TRUETYPE_FONT, new File("C:\\Pacifico.ttf"))
.deriveFont(48 f);
I wrote a little Java program for a friend of mine, we have the same resolution ( 1920 * 1080 ), but his Screen in general is smaller than mine. To solve the problem I gave the GUI elements percentual coordinates, which works perfectly until I use fonts. The Font will be the same size, like mine which is like the code expects. The Bounds for a JButton for example says where to start where to end, but a font measured in points, so each inch has 72 points, a Font with 30 will always be half an inch. (Compare to the Images)
How can I fix this, I found nothing that could solve the problem in my eyes?
Image Before:
https://ibb.co/HXf0pt4
Image After:
https://ibb.co/1sbKyts
public class DrawMenu extends JLabel{
private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int sw = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int sh = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
g.setFont(new Font("TimesRoman", Font.PLAIN, (int)Math.round(sw * 0.0078)));
g.drawString("Termine die nächsten 0 bis 7 Tage", (int)Math.round(sw * 0.026), (int)Math.round(sh * 0.176));
g.drawString("Termine die nächsten 8 bis 14 Tage", (int)Math.round(sw * 0.182), (int)Math.round(sh * 0.176));
repaint();
}
}
public class Gui {
static JFrame jfCounter, jfMenu, jfTask;
static DrawCounter drawc;
static DrawMenu drawm;
static DrawTask drawt;
static JButton kEnde, kNC, kA, kL, kEsc1, kEsc2, kEsc3, kEsc4, kEsc5, kLG, kLB, kAS, kEnter, kJFsw1, kJFsw2, kJFsw3,
kJFsw4, ko[] = new JButton[6], kSettings, ktw, ktla, ktle, ktlb, ktnt;
static JTextArea taAusgabe, taAusgabedw, taAusgabenw, taze, tabe, tati;
static JFormattedTextField nfTag, nfMonat, nfJahr, nfTagA, nfMonatA, nfJahrA;
static JTextField tfAnlass, tfkLBestimmt, tfAnlassA, tfAnlassAS, tfKonsole, tfKonsoleT, tfsettings[] = new JTextField[12], tftw,
tftis, tftlbs, tftnct, tftnci;
public Gui() {
int sw = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int sh = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
System.out.println(sw + " " + sh);
// JFrame Settings
jfCounter = new JFrame();
jfCounter.setSize(sw, sh);
jfCounter.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfCounter.setLocationRelativeTo(null);
jfCounter.setExtendedState(JFrame.MAXIMIZED_BOTH);
jfCounter.setTitle("Tageszähler");
jfMenu = new JFrame();
jfMenu.setSize(sw, sh);
jfMenu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfMenu.setLocationRelativeTo(null);
jfMenu.setExtendedState(JFrame.MAXIMIZED_BOTH);
jfMenu.setTitle("Menü");
jfTask = new JFrame();
jfTask.setSize(sw, sh);
jfTask.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfTask.setLocationRelativeTo(null);
jfTask.setExtendedState(JFrame.MAXIMIZED_BOTH);
jfTask.setTitle("Task");
// JButtons
Border bor = BorderFactory.createLineBorder(Color.BLACK, 1);
Border boresc = BorderFactory.createLineBorder(Color.RED, 3);
kEnde = new JButton("Ende");
kEnde.addActionListener(new ActionHandler());
kEnde.setBounds((int) Math.round(sw * 0.026), (int) Math.round(sh * 0.509), (int) Math.round(sw * 0.195),
(int) Math.round(sh * 0.028));
kEnde.setBorder(bor);
jfCounter.add(kEnde);
kNC = new JButton("Neuer Counter");
kNC.addActionListener(new ActionHandler());
kNC.setBounds((int) Math.round(sw * 0.026), (int) Math.round(sh * 0.028), (int) Math.round(sw * 0.078),
(int) Math.round(sh * 0.028));
kNC.setBorder(bor);
jfCounter.add(kNC);
// JLabel / Draw
drawc = new DrawCounter();
drawc.setBounds(0, 0, sw, sh);
drawc.setVisible(true);
jfCounter.add(drawc);
drawm = new DrawMenu();
drawm.setBounds(0, 0, sw, sh);
drawm.setVisible(true);
jfMenu.add(drawm);
drawt = new DrawTask();
drawt.setBounds(0, 0, sw, sh);
drawt.setVisible(true);
jfTask.add(drawt);
// JFrame Final Visible
Gui.getJfMenu().setVisible(true);
}
im working on a project where i am drawing an image on a JPanel and then putting that panel inside a JScrollPane. The panel itself will vary in size sometimes being smaller than the screen, sometimes larger. When it is larger the scrollpane doesn't seem to have any scroll bars appearing. Im sure im messing something up that is simple but i can't seem to figure it out.
Any help would be greatly appreaciated.
public void createGI(theTicket[] ticketArray){
JFrame ticketReportFrame = new JFrame();
ticketReportFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel ticketReport = new drawTurnoverReport(ticketArray , notes, tapes, turnover);
ticketReport.setBackground(Color.WHITE);
ticketReport.setLayout(new BorderLayout());
JScrollPane ticketReportHolder = new JScrollPane(ticketReport);
ticketReportFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
ticketReportFrame.pack();
ticketReportHolder.setWheelScrollingEnabled(true);
ticketReportFrame.add(ticketReportHolder);
ticketReportFrame.setVisible(true);
ticketReportFrame.setResizable(false);
}
this is just a small portion of drawTurnoverReport to try and help show what i am doing.
public class drawTurnoverReport extends JPanel{
public drawTurnoverReport(theTicket[] tickets, String[] n, String[] t, String[] to){
ticArray = tickets;
notes = n;
tapes = t;
turnover = to;
formalDate = mt.formalDate;
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent( g );
Graphics2D g2 = (Graphics2D) g;
//set fonts
Font tahomaB = new Font("tahoma", Font.BOLD, 15);
Font tahomaP = new Font("tahoma", Font.PLAIN, 15);
//draw heading
g2.setColor(Color.BLACK);
g2.setFont(tahomaB);
Rectangle2D rec = g2.getFontMetrics().getStringBounds("Turnover / Activity Log", g2);
int stringW = (int) rec.getWidth();
int prevStringH = (int) rec.getHeight();
g2.drawString("Turnover / Activity Log", x-(stringW / 2) , 50);
g2.setFont(tahomaP);
rec = g2.getFontMetrics().getStringBounds("Date: " + formalDate, g2);
stringW = (int) rec.getWidth();
verticalPlace = 50 + prevStringH;
g2.drawString("Date: " + formalDate, x-(stringW / 2) , verticalPlace);
prevStringH = (int) rec.getHeight();
verticalPlace += prevStringH;
g2.setFont(tahomaB);
rec = g2.getFontMetrics().getStringBounds("Service Manager Tickets", g2);
stringW = (int) rec.getWidth();
g2.drawString("Service Manager Tickets", x-(stringW / 2) , verticalPlace);
verticalPlace +=2;
g2.drawLine(((int)rec.getMinX()+ x)-(stringW / 2 +2), verticalPlace,
((int)rec.getMaxX()+x)-(stringW / 2), verticalPlace);
verticalPlace += 40;
//draw table headers
verticalUnderHeader = verticalPlace;
g2.drawLine(50, verticalPlace, w-50, verticalPlace);
rec = g2.getFontMetrics().getStringBounds(ticArray[0].getTicketNum(), g2);
stringW = (int) rec.getWidth();
rec = g2.getFontMetrics().getStringBounds("Ticket #", g2);
temp = (int) rec.getWidth();
g2.drawString("Ticket #", ((stringW+65+50)/2-(temp/2)), verticalPlace+17);
horzPlace = stringW + 65;
CNCxA = horzPlace;
rec = g2.getFontMetrics().getStringBounds("Customer Name", g2);
stringW = (int) rec.getWidth();
widthCNC = (horzPlace + stringW + 30)-horzPlace;
g2.drawString("Customer Name", horzPlace + 15, verticalPlace+17);
horzPlace = horzPlace + stringW + 30;
CNCxB = horzPlace;
temp = w-horzPlace+30;
DCx = temp;
widthDC = temp - horzPlace;
rec = g2.getFontMetrics().getStringBounds("Description", g2);
stringW = (int) rec.getWidth();
g2.drawString("Description", (horzPlace+temp)/2-(stringW/2), verticalPlace+17);
rec = g2.getFontMetrics().getStringBounds("Status", g2);
stringW = (int) rec.getWidth();
g2.drawString("Status", (temp+(w-50))/2-(stringW/2), verticalPlace+17);
verticalPlace += 20;
g2.drawLine(50, verticalPlace, w-50, verticalPlace);
verticalPlaceTemp = verticalPlace + 20;
}
}
From the sounds of things, the drawTurnoverReport component isn't providing enough size hint information to the scroll pane.
JScrollPane will use the components preferredSize to determine if it needs to display scroll bars or not.
Ensure you are overriding the getPreferredSize method and return an appropriate size of the component.
For example:
Add an Background image to a Panel
Having images as background of JPanel
This assumes that you are performing some kind of custom painting and not using something like JLabel to render the image, which would then suggest you have a layout issue somewhere...but without the source for drawTurnoverReport, it's impossible to know...
I was looking for a way to rearrange several arguments recived as strings and one byte[] image and put them all togther as one image (jpg for example) ready to be printed (immidiatly).
example:
public static void printCard(String name, String LName, Image MainImage)
Basicly this function will be a simple card printer.
I was looking for an idea or some one who can guide me, this could be very easy if some one will guide me a bit.
This is a simple method that I use to add text onto a pre-existing image.
I'm sure you can work out how to pass a blank image in and add the other lines as you see fit.
private BufferedImage drawText2(BufferedImage bi, String outputText) {
Graphics2D g2d = bi.createGraphics();
g2d.setFont(new Font("Helvetica", Font.BOLD, 36));
FontMetrics fm = g2d.getFontMetrics();
int textWidth = fm.stringWidth(outputText);
int imageWidth = bi.getWidth();
int leftAlignment;
int topAlignment;
// Align the text to the middle
leftAlignment = (imageWidth / 2) - (textWidth / 2);
// Align the text to the top
topAlignment = fm.getHeight() - 10;
// Create the drop shadow
g2d.setColor(Color.DARK_GRAY);
g2d.drawString(outputText, leftAlignment + 2, topAlignment + 2);
// Create the text itself
g2d.setColor(Color.LIGHT_GRAY);
g2d.drawString(outputText, leftAlignment, topAlignment);
g2d.dispose();
return bi;
}
If you want to print directly from your application you can use
java.awt.print package.
Try this method
public static void printCard(final String name, final String lName, final Image mainImage){
Printable contentToPrint = new Printable(){
#Override
public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException {
if (page > 0) {
return NO_SUCH_PAGE;
}
pageFormat.setOrientation(PageFormat.PORTRAIT);
graphics.drawImage(mainImage, 0, 0, null);
graphics.drawString(lName, 100, 300);
graphics.drawString(name, 100, 100);
return PAGE_EXISTS;
}
};
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(contentToPrint);
//You can show a print dialog before printing by job by wrapping the following blocks with a conditional statement if(job.printDialog()){...}
try {
job.print();
} catch (PrinterException e) {
System.err.println(e.getMessage());
}
}
You need to import the print related classes from java.awt.print.
i used graphics2d to impliment my function . this method recive 2 images and 6 strings :
Bufferdimage bi is my blank image, on this image i add objects (ex: image, string) :
private static BufferedImage drawText2(BufferedImage logo,BufferedImage small,BufferedImage bi, String Headline,String outputText2,String outputText3,String outputText4,String outputText5,String outputText6) {
Graphics2D g2d = bi.createGraphics();
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g2d.setRenderingHints(rh);
g2d.setFont(new Font("Arial", Font.BOLD, 50));
FontMetrics fm = g2d.getFontMetrics();
int textWidth = fm.stringWidth(Headline);
int imageWidth = bi.getWidth();
int leftAlignment;
int topAlignment;
// Align the text to the top
topAlignment = fm.getHeight() - 10;
// Create the text itself
//headline
leftAlignment = (imageWidth / 2) - (textWidth);
g2d.setColor(Color.blue);
g2d.drawString(Headline, leftAlignment+290, topAlignment+60);
//property changed
g2d.setFont(new Font("Arial", Font.BOLD, 30));
fm = g2d.getFontMetrics();
textWidth = fm.stringWidth(Headline);
//second line
textWidth = fm.stringWidth(outputText2);
leftAlignment = (imageWidth / 2) - (textWidth);
g2d.setColor(Color.black);
g2d.drawString(outputText2, leftAlignment+290, topAlignment+120);
//third line
textWidth = fm.stringWidth(outputText3);
leftAlignment = (imageWidth / 2) - (textWidth);
g2d.setColor(Color.black);
g2d.drawString(outputText3, leftAlignment+290, topAlignment+160);
//4 line
textWidth = fm.stringWidth(outputText4);
leftAlignment = (imageWidth / 2) - (textWidth);
g2d.setColor(Color.black);
g2d.drawString(outputText4, leftAlignment+290, topAlignment+200);
//5 line
textWidth = fm.stringWidth(outputText5);
leftAlignment = (imageWidth / 2) - (textWidth);
g2d.setColor(Color.black);
g2d.drawString(outputText5, leftAlignment+290, topAlignment+240);
//property changed
g2d.setFont(new Font("Arial", Font.getFont("Arial").HANGING_BASELINE, 20));
fm = g2d.getFontMetrics();
//security line
textWidth = fm.stringWidth(outputText6);
leftAlignment = (textWidth);
g2d.setColor(Color.red);
g2d.drawString(outputText6, 10, topAlignment+300);
//logo
g2d.drawImage (logo, 44, 44,180,70, null);
//profile
g2d.drawImage (small, 60, 120,160,190, null);
g2d.dispose();
return bi;
}
bi is the card with all other objects
btw i added smothing to the font, without this the text is very unpleasent.
I have a Canvas that contains a Label. I want to set font size of this label according to the Canvas size.
How we can do this?
EDIT: "contains" means, Canvas and Label bounds are same.
EDIT2: I have this for Swing, but I couldn't convert it to SWT;
Font labelFont = label.getFont();
String labelText = label.getText();
int stringWidth = label.getFontMetrics(labelFont).stringWidth(labelText);
int componentWidth = label.getWidth();
double widthRatio = (double)componentWidth / (double)stringWidth;
int newFontSize = (int)(labelFont.getSize() * widthRatio);
int componentHeight = label.getHeight();
int fontSizeToUse = Math.min(newFontSize, componentHeight);
EDIT3:
This is my font size calculator class for label
public class FitFontSize {
public static int Calculate(Label l) {
Point size = l.getSize();
FontData[] fontData = l.getFont().getFontData();
GC gc = new GC(l);
int stringWidth = gc.stringExtent(l.getText()).x;
double widthRatio = (double) size.x / (double) stringWidth;
int newFontSize = (int) (fontData[0].getHeight() * widthRatio);
int componentHeight = size.y;
System.out.println(newFontSize + " " + componentHeight);
return Math.min(newFontSize, componentHeight);
}
}
and this is my Label at the top of the window. I want its font size according the volume of Layer size.
Label l = new Label(shell, SWT.NONE);
l.setText("TITLE HERE");
l.setBounds(0,0,shell.getClientArea().width, (shell.getClientArea().height * 10 )/ 100);
l.setFont(new Font(display, "Tahoma", 16,SWT.BOLD));
l.setFont(new Font(display, "Tahoma", FitFontSize.Calculate(l),SWT.BOLD));
I have just ported the code above.
You can get the extent (length) of a String in SWT with the method GC.stringExtent(); and you need the Class FontData to get the font height and font width of the Label.
Label label = new Label(parent, SWT.BORDER);
label.setSize(50, 30);
label.setText("String");
// Get the label size and the font data
Point size = label.getSize();
FontData[] fontData = label.getFont().getFontData();
GC gc = new GC(label);
int stringWidth = gc.stringExtent(label.getText()).x;
// Note: In original answer was ...size.x + (double)..., must be / not +
double widthRatio = (double) size.x / (double) stringWidth;
int newFontSize = (int) (fontData[0].getHeight() * widthRatio);
int componentHeight = size.y;
int fontsizeToUse = Math.min(newFontSize, componentHeight);
// set the font
fontData[0].setHeight(fontsizeToUse);
label.setFont(new Font(Display.getCurrent(), fontData[0]));
gc.dispose();
Sources:
Stackoverflow: Change just the font size in SWT
Eclipse API: GC