问题
It is posible to make a variable in Processing or Java that self contain the typography (ttf or otf) in format of String to be able to load it in the same way that you can do it with images, since LoadImage () works from an array of integers. I can do it with the Images. Is there any way to do it for the case of typography? Thanks!
int[][] var = {
// R G B A
{255, 0, 0, 128},
{ 0, 255, 0, 128}
};
PImage loadPixelsArray(int xDiv, int yDiv, float[][] dots) {
PImage img = createImage(xDiv, yDiv, ARGB);
img.loadPixels();
int size = img.pixels.length;
for (int i = 0; i < size; i++) {
img.pixels[i] = color(dots[i][0], dots[i][1], dots[i][2], dots[i][3]);
}
img.updatePixels();
return img;
}
ps: returns PImage of 2 pixels. I need the same for PFont.
回答1:
There isn't a way to do this without resorting to some pretty gross hacks.
If you're curious, the way you might approach this is by first creating a .vlw
font using George's answer. Then you'd need to write a utility program that reads in the bytes of the file as a byte array, then outputs some syntax that lets you store this as a variable. Copy that variable into your target sketch, and then you could then use a ByteArrayInputStream
to pass the bytes into the PFont
constructor that takes an InputStream
.
So sure, it's possible to do this. But this is very hacky and you should definitely not bother trying it.
Instead, I encourage you to take a step back and think about exactly what you're trying to do. It sounds like you're trying to export a single .exe
file from Processing. Note that this is not possible, even if you use the above hack to get rid of the font file!
Processing exports itself as a directory of run scripts and .jar
files. It is not a single packaged executable file. To convert your Processing sketch into a .exe
file, you're going to have to use something like Launch4J or JWrapper.
Note that these kinds of applications all offer support for packaging external files, which is how you should deal with your font file.
Also note that you could just store your font on the web, and then pass the URL into the loadFont()
function. But again, you'll still have to deal with the multiple .jar
files that Processing exports.
回答2:
In the Processing editor go to Tools > Create Font.. to create a .vlw file (Processing's font format) then in your code simply use loadFont() instead of createFont()
Be sure to run some tests in terms of the right font size and characters (especially if using special characters). In terms of rendering text Processing can do bitmaps or shapes using textMode() depending on the renderer.
Additionally, if you need to create images/pixels of text you can use PGraphics (which extends PImage
)
Update It is still unclear what is that you're asking:
- loading a font from a string(font filename) ?
- render text to an image ?
- get all the gyphs in a font as pixels ? something else ?
If you want to render text to an image, as mentioned above you can use PGraphics:
noSmooth();
PGraphics textImage = createGraphics(25,25);
textImage.beginDraw();
textImage.text("O!",10,15);
textImage.endDraw();
image(textImage,0,0);
image(textImage,0,0,textImage.width * 2.1,textImage.height * 2.1);
image(textImage,0,0,textImage.width * 4.5,textImage.height * 4.5);
For more details on PFont use the PFont javadoc. Notice you can get glyphs (which have images):
String[] fontNames = {"Monospaced","ProcessingSansPro-Regular"};
int NUM_FONTS = fontNames.length;
PFont[] fonts = new PFont[NUM_FONTS];
PFont font;
int FONT_SIZE = 30;
String message = "Hello World";
ArrayList<PImage> glyphImages;
void setup(){
size(300,300);
textAlign(CENTER);
fill(0);
// load fonts
for(int i = 0 ; i < NUM_FONTS; i++){
fonts[i] = createFont(fontNames[i],FONT_SIZE);
}
// set first font
setFont(0);
}
void draw(){
background(255);
text(message,width * 0.5,height * 0.5);
drawGlyphImages();
}
void keyPressed(){
if(key == '1'){
setFont(0);
}
if(key == '2'){
setFont(1);
}
}
void setFont(int fontIndex){
// check font data is accessible
if(fonts != null){
if(fontIndex >= 0 && fontIndex < fonts.length){
// update global reference to currently set font
font = fonts[fontIndex];
// tell Processing to use this font
textFont(font,FONT_SIZE);
// create glyph images
glyphImages = getGlyphImages(font,message);
}else{
println("error: invalid array index",fontIndex,"valid range is",0,fonts.length-1);
}
}else{
println("error: null fonts array");
}
}
ArrayList<PImage> getGlyphImages(PFont font,String message){
ArrayList<PImage> result = new ArrayList<PImage>();
// access font glyph images
for(int i = 0 ; i < message.length(); i++){
// get the each character
char currentChar = message.charAt(i);
// get the glyph
PFont.Glyph glyph = font.getGlyph(currentChar);
// if there is a glyph (space or other special character might not be encoded in the font file)
if(glyph != null){
// get a copy of the glyph image
PImage glyphImage = glyph.image.get();
// glyph PImages are in ALPHA format: for demo purposes we use a GRAY filter to set the format to RGB
glyphImage.filter(GRAY);
// append the glyph image to the list
result.add(glyphImage);
}
}
return result;
}
ArrayList<PShape> getGlyphShapes(PFont font,String message){
ArrayList<PShape> result = new ArrayList<PShape>();
// access font glyph images
for(int i = 0 ; i < message.length(); i++){
// get the each character
char currentChar = message.charAt(i);
// get the glyph shape
PShape glyphShape = font.getShape(currentChar);
// if there is a glyph (space or other special character might not be encoded in the font file)
if(glyphShape != null){
// add the shape to the list
result.add(glyphShape);
}
}
return result;
}
void drawGlyphImages(){
float previousGlyphsHeight = 0;
for(int i = 0; i < glyphImages.size(); i++){
PImage glyphImage = glyphImages.get(i);
image(glyphImage,10,glyphImage.height + previousGlyphsHeight,glyphImage.width * 2,glyphImage.height * 2);
previousGlyphsHeight += (glyphImage.height * 2) + 3;
}
}
Additionally you can get the shapes via PFont's [getShape()][9]
:
String[] fontNames = {"Monospaced","ProcessingSansPro-Regular"};
int NUM_FONTS = fontNames.length;
PFont[] fonts = new PFont[NUM_FONTS];
PFont font;
int FONT_SIZE = 30;
String message = "Hello World";
ArrayList<PShape> glyphShapes;
void setup(){
size(345,345);
textAlign(CENTER);
fill(0);
// load fonts
for(int i = 0 ; i < NUM_FONTS; i++){
fonts[i] = createFont(fontNames[i],FONT_SIZE);
}
// set first font
setFont(0);
}
void draw(){
background(255);
text(message,width * 0.5,height * 0.5);
drawGlyphShapes();
}
void keyPressed(){
if(key == '1'){
setFont(0);
}
if(key == '2'){
setFont(1);
}
}
void setFont(int fontIndex){
// check font data is accessible
if(fonts != null){
if(fontIndex >= 0 && fontIndex < fonts.length){
// update global reference to currently set font
font = fonts[fontIndex];
// tell Processing to use this font
textFont(font,FONT_SIZE);
// update glyph shapes
glyphShapes = getGlyphShapes(font,message);
}else{
println("error: invalid array index",fontIndex,"valid range is",0,fonts.length-1);
}
}else{
println("error: null fonts array");
}
}
ArrayList<PShape> getGlyphShapes(PFont font,String message){
ArrayList<PShape> result = new ArrayList<PShape>();
// access font glyph images
for(int i = 0 ; i < message.length(); i++){
// get the each character
char currentChar = message.charAt(i);
// get the glyph shape
PShape glyphShape = font.getShape(currentChar);
// if there is a glyph (space or other special character might not be encoded in the font file)
if(glyphShape != null){
// add the shape to the list
result.add(glyphShape);
}
}
return result;
}
void drawGlyphShapes(){
float maxGlyphHeight = 30;
for(int i = 0; i < glyphShapes.size(); i++){
PShape glyphShape = glyphShapes.get(i);
glyphShape.disableStyle();
noFill();
beginShape();
for(int j = 0 ; j < glyphShape.getVertexCount(); j++){
PVector vertex = glyphShape.getVertex(j);
vertex(10 + vertex.x,vertex.y + 30 + glyphShape.getHeight() + (maxGlyphHeight * i));
}
endShape(CLOSE);
}
}
If you want to draw your own glyphs you can always use beginShape(), createShape(), etc. and wrap it in a function that takes the string you want to render and draws the correct shapes for each character.
If you want to create your own ttf font file you may need an external library. Have a look at the Typography Processing libraries for extended functionality.
来源:https://stackoverflow.com/questions/52818958/createfont-from-string