Ok here are the details:
I need to get an image from the user. Than i have to add text on this image. this is very simple. The problem is that i have to give engrave effect to text. This is the difficult part. I have tried diffrent methods. but non of them work. I was able to give emboss effect to text but not the engrave effect.
public void paintComponent(Graphics go){
//System.out.println("Go");
Graphics2D g = (Graphics2D)go;
RenderingHints hints = new RenderingHints(null);
int n=0;
if(flags[n++])
hints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if(flags[n++])
hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
if(flags[n++])
hints.put(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
if(flags[n++])
hints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
if(flags[n++])
hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
if(flags[n++])
hints.put(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
if(flags[n++])
hints.put(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_NORMALIZE);
if(flags[n++])
hints.put(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
hints.put(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.setRenderingHints(hints);
if(shape==null){
start = System.currentTimeMillis();
Font font = getFont();
font = font.deriveFont(Font.BOLD, textSize);
//new Font(font.getFontName(), Font.BOLD, textSize);
Stroke bs = new BasicStroke(fatten);
//g.setStroke(bs);
GlyphVector gv = font.createGlyphVector(g.getFontRenderContext(),
text);
// 1 degrees = 0.0174532925 radians
int maxTilt = 20;
GeneralPath path = new GeneralPath();
Random random = new Random();
if(jiggle){
for(int i=0;i<gv.getNumGlyphs();i++){
double r = (random.nextInt(2*maxTilt)-maxTilt)*0.0174532925;
AffineTransform trans = gv.getGlyphTransform(i);
Shape sh = gv.getGlyphOutline(i);
Rectangle shr = sh.getBounds();
double cx = shr.getCenterX();
double cy = shr.getCenterY();
// jdk1.5 return null?
if(trans==null)
trans = new AffineTransform();
trans.rotate(r,cx,cy);
////gv.setGlyphTransform(i, trans);
////trans = gv.getGlyphTransform(i);
path.transform(trans);
path.append(sh,false);
try{
path.transform(trans.createInverse());
}catch(Exception e){System.out.println("foo");}
}
}else{
path.append(gv.getOutline(),false);
}
//gv.set
if(fatten==0){
shape = path;
}else{
// What we need is something like photoshop's expand selection.
// The following is very slow...
Area area = new Area(path);
area.add(new Area(bs.createStrokedShape(path)));
shape = area;
// This creates a disconnected outline, which isn't right,
// but much faster ;)
/*GeneralPath p2 = new GeneralPath(path);
p2.append(bs.createStrokedShape(path), false);
shape = p2;*/
}
/*if(ringed){
Area area = null;
Area comp = new Area();;
//if(shape instanceof Area)
//area = (Area)shape;
//else
area = new Area(shape);
Stroke empty = new BasicStroke(10);
comp.add(new Area(shape));
comp.add(new Area(empty.createStrokedShape(shape)));
Stroke ring = new BasicStroke(3);
area.add(new Area(ring.createStrokedShape(comp)));
shape = area;
}*/
Stroke stroke = new BasicStroke(2);
outline = stroke.createStrokedShape(shape);
end = System.currentTimeMillis();
msg = "Build time "+(end-start)+" ms";
}
Rectangle r = shape.getBounds();
//g.clearRect(0,0,getWidth(),getHeight());
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
Rectangle bg = new Rectangle(0,0,getWidth(),getHeight());
if(glassBG)
paintGlassEffect(g, bg, getBackground());
int x = (getWidth()-r.width)/2;
int y = (getHeight()-r.height)/2;
y -= r.y/2;
g.setColor(Color.BLACK);
g.translate(x,y);
// Show bounding box
//g.draw(r);
paintText(g);
g.translate(-x,-y);
g.setColor(getTextColor());
g.drawString(msg, 5, getHeight()-5);
}
This is the code i am using to give emboss effect. How can i give engrave effect to text or images in java?>
hi,
why don't you try to draw the text in semi-transparent black when you want it darker than the image and in semi-transparent white when you want it lighter using the same technique as described in the rose india link previously sent to you.
It would probably be even better if you code a Photoshop-like 'overlay' or 'multiply' mode instead of pure AlphaCompositing. Anyway using the AlphaComposite at first shoul do the job.
Let me know.
Vince.
Hi,
here is what I would do:
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
Composite oldComp = g2d.getComposite();
g2d.drawImage(your_background_image);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.setColor(Color.white);
g2d.drawString("Engrave Text", textX+1, textY+1);
g2d.setColor(Color.black);
g2d.drawString("Engrave Text", textX, textY);
g2d.setComposite(oldComp);
}
You can tune the transparency level and eventually change the white color into yellow for example.
Let me know if this match your expectations.
Cheers.
Vince.
Thanks for your reply. But the problem is still there. It blured the figure. but the results are not satisfactory.
Here is the code i am trying.
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Composite oldComp = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g.setFont(font);
g.drawImage(bkImage, x, y, null);
g.setColor(getMainColor().darker());
g.drawString(name, textX+1, textY+1);
g.setColor(getMainColor().brighter());
g.drawString(name, textX, textY);
g.setColor(Color.BLACK);
g.drawImage(topImage, x+20, y+66, null);
g.drawImage(middleImage, x+20, y+116, null);
g.drawImage(bottomImage, x+20, y+166, null);
g2d.setComposite(oldComp);
}
I think there is one more problem. Which is when engraving any text upon any image you must make text colored same as image.
Hi,
in the code you posted, you are not doing things in the correct order.
You are drawing the dark text first instead of the light text. This does not produce an engraved effect but more a shadow/blur effect.
Here is what I would do instead:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Composite oldComp = g2d.getComposite();
// first draw bkg image without transparency
g2d.drawImage(bkImage, x, y, null);
g2d.setFont(font);
//then semi-transparent white text to generate reflects from the background image colors
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.setColor(Color.white);
g2d.drawString(name, textX+1, textY+1);
//then semi-transparent black to get the inside shadow of the engraved text
g2d.setColor(Color.black);
g2d.drawString(name, textX, textY);
//then come back to original non-transparent blending (if this is what you want)
g2d.setComposite(oldComp);
g2d.setColor(Color.BLACK);
g2d.drawImage(topImage, x+20, y+66, null);
g2d.drawImage(middleImage, x+20, y+116, null);
g2d.drawImage(bottomImage, x+20, y+166, null);
}
Let me know if this gets closer to what you're looking for. I tried it on several backgrounds and it gives nice results.
Cheers.