Is there a way in Java to get the native font name from a Font object?
I get my Font using this code Font.decode("Serif") and for debugging purpose I would like to know the native font used.
It might not be that simple. Some fonts are composed of many physical fonts, using different physical fonts for different glyphs.
For example, on my Windows system the Serif font uses 12 physical fonts:
** TrueType Font: Family=Times New Roman Name=Times New Roman style=0 fileName=C:\Windows\Fonts\TIMES.TTF
** TrueType Font: Family=Wingdings Name=Wingdings style=0 fileName=C:\Windows\Fonts\WINGDING.TTF
** TrueType Font: Family=Symbol Name=Symbol style=0 fileName=C:\Windows\Fonts\SYMBOL.TTF
** TrueType Font: Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0_37\jre\lib\fonts\LucidaSansRegular.ttf
** TrueType Font: Family=MingLiU Name=MingLiU style=0 fileName=C:\Windows\Fonts\MINGLIU.TTC
** TrueType Font: Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0_37\jre\lib\fonts\LucidaSansRegular.ttf
** TrueType Font: Family=SimSun Name=SimSun style=0 fileName=C:\Windows\Fonts\SIMSUN.TTC
** TrueType Font: Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0_37\jre\lib\fonts\LucidaSansRegular.ttf
** TrueType Font: Family=MS Mincho Name=MS Mincho style=0 fileName=C:\Windows\Fonts\MSMINCHO.TTC
** TrueType Font: Family=Batang Name=Batang style=0 fileName=C:\Windows\Fonts\batang.TTC
** TrueType Font: Family=MingLiU-ExtB Name=MingLiU-ExtB style=0 fileName=C:\Windows\Fonts\MINGLIUB.TTC
** TrueType Font: Family=SimSun-ExtB Name=SimSun-ExtB style=0 fileName=C:\Windows\Fonts\SIMSUNB.TTF
The following code can break down a font into its physical components. It uses a reflection hack to access a sun.awt.Font2D object, so use at your own risk (works with Oracle Java 6u37):
import java.awt.Font;
import java.lang.reflect.Method;
import java.util.Locale;
import sun.font.CompositeFont;
import sun.font.Font2D;
import sun.font.PhysicalFont;
public class FontTester
{
public static void main(String... args)
throws Exception
{
Font font = new Font("Serif", Font.PLAIN, 12);
describeFont(font);
}
private static void describeFont(Font font)
throws Exception
{
Method method = font.getClass().getDeclaredMethod("getFont2D");
method.setAccessible(true);
Font2D f = (Font2D)method.invoke(font);
describeFont2D(f);
}
private static void describeFont2D(Font2D font)
{
if (font instanceof CompositeFont)
{
System.out.println("Font '" + font.getFontName(Locale.getDefault()) + "' is composed of:");
CompositeFont cf = (CompositeFont)font;
for (int i = 0; i < cf.getNumSlots(); i++)
{
PhysicalFont pf = cf.getSlotFont(i);
describeFont2D(pf);
}
}
else
System.out.println("-> " + font);
}
}
prunge's answer was nearly perfect, except that it didn't actually expose the native (physical) font's name. The following tiny change to the describeFont2D method does the trick by again leveraging Java reflection:
Don't forget to import java.lang.reflect.Field;
private static void describeFont2D( Font2D font ) throws Exception{
if( font instanceof CompositeFont ){
System.out.println( "Font '"+font.getFontName( Locale.getDefault() )+"' is composed of:" );
CompositeFont cf = ( CompositeFont )font;
for( int i = 0; i<cf.getNumSlots(); i++ ){
PhysicalFont pf = cf.getSlotFont( i );
describeFont2D( pf );
}
}else if( font instanceof CFont ){
Field field = CFont.class.getDeclaredField( "nativeFontName" );
field.setAccessible( true );
String nativeFontName = ( String )field.get( font );
System.out.println( "-> "+nativeFontName );
}else
System.out.println( "-> "+font );
}
This code will get the system fonts if they are available, and will get default families if for some reason they are not available:
static String[] AS_System_Fonts = null;
public static String[] getFontFamilies(){
if( AS_System_Fonts != null ) return AS_System_Fonts;
java.awt.GraphicsEnvironment gEnv = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
AS_System_Fonts = gEnv.getAvailableFontFamilyNames();
if( AS_System_Fonts == null ){ // should not happen
AS_System_Fonts = new String[8];
AS_System_Fonts[0] = "Serif";
AS_System_Fonts[1] = "Sans-Serif";
AS_System_Fonts[2] = "Monospaced";
AS_System_Fonts[3] = "Dialog";
AS_System_Fonts[4] = "Dialog Input";
AS_System_Fonts[5] = "Lucida Bright";
AS_System_Fonts[6] = "Lucida Sans";
AS_System_Fonts[7] = "Lucida Sans Typewriter";
}
return AS_System_Fonts;
}
Related
I am investigating Java PDF libraries.
I have a tried
org.apache.pdfbox
File file = new File("file.pdf");
PDDocument document = PDDocument.load(file);
// Instantiate PDFTextStripper class
PDFTextStripper pdfStripper = new PDFTextStripper();
// Retrieving text from PDF document
String text = pdfStripper.getText(document);
System.out.println(text);
// Closing the document
document.close();
com.itextpdf.text.pdf
public static final String SRC = "file.pdf";
public static final String DEST = "streams";
public static void main(final String[] args) throws IOException {
File file = new File(DEST);
new BruteForce().parse(SRC, DEST);
}
public void parse(final String src, final String dest) throws IOException {
PdfReader reader = new PdfReader(src);
PdfObject obj;
for (int i = 1; i <= reader.getXrefSize(); i++) {
obj = reader.getPdfObject(i);
if ((obj != null) && obj.isStream()) {
PRStream stream = (PRStream) obj;
byte[] b;
try {
b = PdfReader.getStreamBytes(stream);
} catch (UnsupportedPdfException e) {
b = PdfReader.getStreamBytesRaw(stream);
}
FileOutputStream fos = new FileOutputStream(String.format(dest, i));
fos.write(b);
fos.flush();
fos.close();
} else {
final PdfDictionary pdfDictionary = (PdfDictionary) obj;
System.out.println("\t>>>>> " + pdfDictionary + "\t\t" + pdfDictionary.getKeys());
final Set<PdfName> pdfNames = pdfDictionary.getKeys();
for (final PdfName pdfName : pdfNames) {
final PdfObject pdfObject = pdfDictionary.get(pdfName);
final int type = pdfObject.type();
switch (type) {
case PdfObject.NULL:
System.out.println("\t NULL " + pdfObject);
break;
case PdfObject.BOOLEAN:
System.out.println("\t BOOLEAN " + pdfObject);
break;
case PdfObject.NUMBER:
System.out.println("\t NUMBER " + pdfObject);
break;
case PdfObject.STRING:
System.out.println("\t STRING " + pdfObject);
break;
case PdfObject.NAME:
System.out.println("\t NAME " + pdfObject);
break;
case PdfObject.ARRAY:
System.out.println("\t ARRAY " + pdfObject);
break;
case PdfObject.DICTIONARY:
System.out.println("\t DICTIONARY " + ((PdfDictionary)pdfObject).getKeys());
break;
case PdfObject.STREAM:
System.out.println("\t STREAM " + pdfObject);
break;
case PdfObject.INDIRECT:
System.out.println("\t INDIRECT " +pdfObject.getIndRef());
break;
default:
}
System.out.println("\t\t--- " + pdfObject.type());
}
}
}
}
com.snowtide.pdf
String pdfFilePath = "file.pdf";
Document pdf = PDF.open(pdfFilePath);
final List<Annotation> annotations = pdf.getAllAnnotations();
for (final Annotation annotation : annotations) {
System.out.println(annotation.pageNumber());
}
System.out.println(pdf.getAttributeMap());
System.out.println(pdf.getAttributeKeys());
System.out.println("=============================");
StringBuilder text = new StringBuilder(1024);
pdf.pipe(new OutputTarget(text));
pdf.close();
System.out.println(text);
I can extract all visible PDF content including links, text, and images apart from what appears to be a "Watermark" that appears on every page.
Can PDF documents contain "unreachable" content?
Is there no way to extract ALL content from a PDF file?
UPDATE
thinking the "watermark" was an image I tried this code
File fileW = new File("file.pdf");
PDDocument document = PDDocument.load(fileW);
PDPageTree list = document.getPages();
for (PDPage page : list) {
PDResources pdResources = page.getResources();
for (COSName c : pdResources.getXObjectNames()) {
System.out.println("????? ::>>>" + c);
PDXObject o = pdResources.getXObject(c);
if (o instanceof org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject) {
File file = new File("Temp/" + System.nanoTime() + ".png");
ImageIO.write(((org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject) o).getImage(), "png", file);
} else {
}
}
}
The PDF does contain images of the authors, however the "watermark" is not reached with this approach.
The page content streams of the example document provided by the OP have the following structure from page 2 onward:
A textual header line "www.electrophoresis-journal.com Page X Electrophoresis":
BT
/F1 9.12 Tf
1 0 0 1 72.024 798.46 Tm
/GS7 gs
0 g
0 G
[(w)11(w)11(w)11(.)-12(e)-2(l)15(e)-2(c)23(t)-10(r)-8(o)26(pho)26(r)-8(e)-2(s)21(i)-10(s)] TJ
ET
[...]
BT
1 0 0 1 441.53 798.46 Tm
[(E)6(l)-10(e)-2(c)23(t)-10(r)-8(o)26(pho)26(r)-8(e)23(s)-5(i)15(s)] TJ
ET
BT
1 0 0 1 497.47 798.46 Tm
[( )] TJ
ET
BT
1 0 0 1 72.024 787.9 Tm
[( )] TJ
ET
This text can easily be extracted using normal iText or PDFBox text extraction.
A textual multi-line footer "Received: ... All rights reserved."
BT
1 0 0 1 72.024 109.7 Tm
[(R)9(e)-2(c)23(e)-2(i)-10(v)26(e)-2(d:)41( )] TJ
ET
[...]
BT
1 0 0 1 72.024 47.76 Tm
[(T)6(hi)-10(s)21( )-12(a)23(r)-8(t)15(i)-10(c)23(l)-10(e)23( )13(i)-10(s)21( )-12(pr)-8(o)26(t)15(e)-2(c)23(t)-10(e)-2(d)26( )-12(by)53( )-12(c)-2(o)26(p)-25(y)53(r)-8(i)-10(g)26(ht)-10(.)-12( )-12(A)38(l)-10(l)15( )13(r)-8(i)-10(g)26(ht)15(s)-5( )13(r)-8(e)23(s)-5(e)-2(r)-8(v)26(e)-2(d)26(.)] TJ
ET
BT
1 0 0 1 278.52 47.76 Tm
[( )] TJ
ET
BT
1 0 0 1 72.024 37.2 Tm
[( )] TJ
ET
This text also can easily be extracted using normal iText or PDFBox text extraction.
A set of PDF path creation and filling operations using a custom graphics state forming the transparent "Accepted Article" writing on the left of the page:
/GS8 gs
0 g
39.605 266.51 m
39.605 261.29 39.605 256.06 39.605 250.84 c
42.197 249.94 44.776 248.99 47.367 248.09 c
49.296 247.41 50.704 247.08 51.649 247.08 c
52.413 247.08 53.058 247.38 53.609 247.97 c
54.191 248.54 54.548 249.82 54.729 251.77 c
55.18 251.77 55.624 251.77 56.075 251.77 c
56.075 247.51 56.075 243.26 56.075 239.02 c
55.624 239.02 55.18 239.02 54.729 239.02 c
54.36 240.72 53.903 241.8 53.314 242.3 c
52.144 243.3 49.809 244.47 46.247 245.67 c
32.719 250.33 19.286 255.25 5.7645 259.91 c
5.7645 260.26 5.7645 260.61 5.7645 260.95 c
19.43 265.57 33.014 270.43 46.679 275.05 c
49.984 276.16 52.075 277.24 53.064 278.15 c
54.053 279.06 54.623 280.36 54.729 282 c
55.18 282 55.624 282 56.075 282 c
56.075 276.68 56.075 271.35 56.075 266.03 c
55.624 266.03 55.18 266.03 54.729 266.03 c
54.623 267.64 54.303 268.75 53.753 269.31 c
53.202 269.88 52.519 270.15 51.718 270.15 c
50.666 270.15 48.97 269.75 46.679 268.95 c
44.319 268.15 41.971 267.31 39.605 266.51 c
h
36.92 265.67 m
30.284 263.43 23.686 261.05 17.045 258.81 c
23.686 256.5 30.284 254.07 36.92 251.77 c
36.92 256.4 36.92 261.04 36.92 265.67 c
h
f*
[...]
35.361 630.34 m
40.294 630.31 44.156 631.32 46.967 633.29 c
49.784 635.27 51.18 637.63 51.18 640.31 c
51.18 642.1 50.573 643.67 49.364 645 c
48.156 646.3 46.141 647.43 43.236 648.31 c
43.48 648.62 43.712 648.93 43.962 649.24 c
47.261 648.83 50.253 647.57 52.989 645.6 c
55.731 643.62 57.089 641.06 57.089 638.05 c
57.089 634.76 55.549 631.92 52.413 629.63 c
49.302 627.3 45.158 626.1 39.899 626.1 c
34.203 626.1 29.802 627.33 26.585 629.71 c
23.405 632.07 21.834 635.12 21.834 638.73 c
21.834 641.8 23.048 644.34 25.496 646.28 c
27.981 648.22 31.267 649.24 35.361 649.24 c
35.361 642.94 35.361 636.64 35.361 630.34 c
h
33.258 630.34 m
33.258 634.56 33.258 638.78 33.258 643 c
31.117 642.91 29.633 642.7 28.763 642.37 c
27.417 641.87 26.341 641.14 25.571 640.16 c
24.801 639.19 24.406 638.13 24.406 637.06 c
24.406 635.42 25.158 633.91 26.729 632.64 c
28.306 631.34 30.466 630.55 33.258 630.34 c
h
f*
(The instructions I quoted draw the initial 'A' and the final 'e'.)
This writing cannot be extracted using normal iText or PDFBox text extraction as it neither is drawn using text instruction nor is marked with an ActualText entry. (The latter could be recognized using customized iText or PDFBox text extraction.)
But you can extract this writing as the sequence of path creation and drawing commands it consists of using an implementation of the iText ExtRenderListener interface or a subclass of the PDFBox PDFGraphicsStreamEngine.
The actual text content of the article, opaque, using text drawing instructions, e.g.
BT
/F2 10.08 Tf
1 0 0 1 72.024 760.78 Tm
/GS7 gs
0 g
[(H)-7(I)8(G)16(H)-7( )-106(TH)-6(R)32(O)-7(U)8(G)16(H)-7(P)16(U)8(T )-106(M)-7(U)8(LTI)] TJ
ET
BT
1 0 0 1 212.98 760.78 Tm
[(-)] TJ
ET
BT
1 0 0 1 216.1 760.78 Tm
[(O)-7(R)8(G)-7(A)8(N)32( )-130(M)15(ETA)32(BO)-6(LO)16(M)-7(I)8(C)8(S)8( )-130(I)8(N)8( )-106(TH)-6(E)24( )-130(A)8(P)16(P)16(/)-7(P)16(S)8(1 )-106(M)-7(O)-7(U)8(S)8(E)24( )-130(M)15(O)-7(D)8(EL)24( )-106(O)-7(F)16( )] TJ
ET
This text also can easily be extracted using normal iText or PDFBox text extraction.
Concerning the OP's questions, therefore,
I can extract all visible PDF content including links, text, and images apart from what appears to be a "Watermark" that appears on every page.
Can PDF documents contain "unreachable" content?
That content is not "unreachable", it merely is not text drawn using text drawing instructions but instead text drawn like an arbitrary shape.
Is there no way to extract ALL content from a PDF file?
You can extract that content, merely not as text but instead as a collection of path creation and drawing instructions. Whenever you suspect such instructions to actually draw letter shapes, you can try to determine the text by rendering these paths as a bitmap and applying OCR.
I am trying to read mainframe file but all are working other than comp 3 file.Below program is giving strange values.It is not able to read the salary value which is double also it is giving 2020202020.20 values. I don't know what am missing.Please help me to find it.
Program:
public final class Readcopybook {
private String dataFile = "EMPFILE.txt";
private String copybookName = "EMPCOPYBOOK.txt";
public Readcopybook() {
super();
AbstractLine line;
try {
ICobolIOBuilder iob = JRecordInterface1.COBOL.newIOBuilder(copybookName)
.setFileOrganization(Constants.IO_BINARY_IBM_4680).setSplitCopybook(CopybookLoader.SPLIT_NONE);
AbstractLineReader reader = iob.newReader(dataFile);
while ((line = reader.read()) != null) {
System.out.println(line.getFieldValue("EMP-NO").asString() + " "
+ line.getFieldValue("EMP-NAME").asString() + " "
+ line.getFieldValue("EMP-ADDRESS").asString() + " "
+ line.getFieldValue("EMP-SALARY").asString() + " "
+ line.getFieldValue("EMP-ZIPCODE").asString());
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Readcopybook();
}
}
EMPCOPYBOOK:
001700 01 EMP-RECORD.
001900 10 EMP-NO PIC 9(10).
002000 10 EMP-NAME PIC X(30).
002100 10 EMP-ADDRESS PIC X(30).
002200 10 EMP-SALARY PIC S9(8)V9(2) COMP-3.
002200 10 EMP-ZIPCODE PIC 9(4).
EMPFILE:
0000001001suneel kumar r bangalore e¡5671
0000001002JOSEPH WHITE FIELD rrn4500
Output:
1001 suneel kumar r bangalore 20200165a10 5671
2020202020.20
2020202020.20
2020202020.20
2020202020.20
2020202020.20
2020202020.20
2020202020.20
2020202020.20
0.00
1002 JOSEPH WHITE FIELD 202072726e0 4500
One problem is you have done a Ebcdic to Ascii conversion on the file.
The 2020... is a dead give away x'20' is the ascii space character.
This Answer deals with problems with doing an Ebcdic to ascii conversion.
You need to do a Binary transfer from the Mainframe and read the file using Ebcdic. You will need to check the RECFM on the Mainframe. If the RECFM is
FB - problems just transfer
VB - either convert to FB on the mainframe of include the RDW (Record Descriptor Word) option in the transfer.
Other - Convert to FB/VB on the mainframe
Updated java Code
int fileOrg = Constants.IO_FIXED_LENGTH_RECORDS; // or Constants.IO_VB
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder(copybookName)
.setFileOrganization(fileOrg)
.setFont("Cp037")
.setSplitCopybook(CopybookLoader.SPLIT_NONE);
Note: IO_BINARY_IBM_4680 is for IBM 4690 Registers
There is a wiki entry here
or this Question
How do you generate java~jrecord code fror a Cobol copybook
In a swing application, I need to foresee text wrapping of a string like when putting it in a word processor program such as MS Word or LibreOffice. Providing the same width of the displayable area, the same font (face and size) and the same string as following:
displayable area width: 179mm (in a .doc file, setup an A4 portrait page - width = 210mm, margin left = 20mm, right = 11mm; the paragraph is formatted with zero margins)
Font Times New Roman, size 14
Test string: Tadf fdas fdas daebjnbvx dasf opqwe dsa: dfa fdsa ewqnbcmv caqw vstrt vsip d asfd eacc
And the result:
On both MS Word and LibreOffice, that test string is displayed on single line, no text wrapping occurs.
My bellow program report a text wrapping occurs, 2 lines
Line 1: Tadf fdas fdas daebjnbvx dasf opqwe dsa: dfa fdsa ewqnbcmv caqw vstrt vsip d asfd
Line 2: eacc
Is it possible to achieve the same text wrapping effect like MS Word in swing? What could be wrong in the code?
Bellow the my program
public static List<String> wrapText(String text, float maxWidth,
Graphics2D g, Font displayFont) {
// Normalize the graphics context so that 1 point is exactly
// 1/72 inch and thus fonts will display at the correct sizes:
GraphicsConfiguration gc = g.getDeviceConfiguration();
g.transform(gc.getNormalizingTransform());
AttributedCharacterIterator paragraph = new AttributedString(text).getIterator();
Font backupFont = g.getFont();
g.setFont(displayFont);
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(
paragraph, BreakIterator.getWordInstance(), g.getFontRenderContext());
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraph.getBeginIndex());
List<String> lines = new ArrayList<String>();
int beginIndex = 0;
// Get lines until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraph.getEndIndex()) {
lineMeasurer.nextLayout(maxWidth);
lines.add(text.substring(beginIndex, lineMeasurer.getPosition()));
beginIndex = lineMeasurer.getPosition();
}
g.setFont(backupFont);
return lines;
}
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextPane txtp = new JTextPane();
frame.add(txtp);
frame.setSize(200,200);
frame.setVisible(true);
Font displayFont = new Font("Times New Roman", Font.PLAIN, 14);
float textWith = (179 * 0.0393701f) // from Millimeter to Inch
* 72f; // From Inch to Pixel (User space)
List<String> lines = wrapText(
"Tadf fdas fdas daebjnbvx dasf opqwe dsa: dfa fdsa ewqnbcmv caqw vstrt vsip d asfd eacc",
textWith,
(Graphics2D) txtp.getGraphics(),
displayFont);
for (int i = 0; i < lines.size(); i++) {
System.out.print("Line " + (i + 1) + ": ");
System.out.println(lines.get(i));
}
frame.dispose();
}
+1 for the question
From my experience with text editors it's not possible to achieve exactly the same measuring.
You can try to play with DPI there is default DPI=72 and 96 on windows.
Also you can try to play with all the rendering hints of the Graphics - text antialiasing etc.
my problem is:
i have made a 3D model with texture in Cinema 4d ( similiar to this one : http://preview.turbosquid.com/Preview/2011/03/30__13_54_17/space%20shuttle%206.jpgeec17db2-6651-453c-9d27-ea1908e3c7dfLarge.jpg )
Now i want to export it to my jMonkeyEngine to set it up in my scene and to animate it.
I tried to export my model as a .obj-file and load it into my projekt (just the .obj-file).
The result is that i have no textures! What do i wrong?
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
/**
* test
* #author normenhansen
*/
public class Main extends SimpleApplication {
public static void main(String[] args) {
Main app = new Main();
app.start();
}
#Override
public void simpleInitApp() {
//Modell laden
Spatial spaceShuttle =assetManager.loadModel("Models/test/space.obj");
//Skalieren
spaceShuttle.scale(0.005f, 0.005f, 0.005f);
//Szenenbaum erstellen
Node sceneNode = new Node("sceneNode");
Node geometryNode = new Node("geometryNode");
Node lightNode = new Node("lightNode");
sceneNode.attachChild(lightNode);
sceneNode.attachChild(geometryNode);
rootNode.attachChild(sceneNode);
//neue Elemente in den Baum Einfügen
geometryNode.attachChild(spaceShuttle);
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(1,0,-2).normalizeLocal());
sun.setColor(ColorRGBA.White);
rootNode.addLight(sun);
}
#Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
#Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
You're not doing anything wrong. C4D exports just the .obj, but no .mtl by default.
I know that's true for C4D R11.5 and R12, not sure about newer ones.
You'll can write a script to export the .mtl as well.
Here's a Python snippet for reference:
#save mtl
mcount = 0;
mtl = ''
for tag in op.GetTags():
if(tag.GetType() == 5616): #texture tag
mcount += 1
m = tag.GetMaterial()
mtl += 'newmtl '+clean(m.GetName())+'\n'
if(m[sy.MATERIAL_COLOR_COLOR]): mtl += 'Kd ' + str(m[sy.MATERIAL_COLOR_COLOR].x) + ' ' + str(m[sy.MATERIAL_COLOR_COLOR].y) + ' ' + str(m[sy.MATERIAL_COLOR_COLOR].z) + '\n'
if(m[sy.MATERIAL_SPECULAR_COLOR]): mtl += 'Ks ' + str(m[sy.MATERIAL_SPECULAR_COLOR].x) + ' ' + str(m[sy.MATERIAL_SPECULAR_COLOR].y) + ' ' + str(m[sy.MATERIAL_SPECULAR_COLOR].z) + '\n'
if(m[sy.MATERIAL_SPECULAR_BRIGHTNESS]): mtl += 'Ns ' + str(m[sy.MATERIAL_SPECULAR_BRIGHTNESS]) + '\n'
if(m[sy.MATERIAL_TRANSPARENCY_BRIGHTNESS]): mtl += 'd ' + str(m[sy.MATERIAL_TRANSPARENCY_BRIGHTNESS]) + '\n'
if(m[sy.MATERIAL_COLOR_SHADER]): mtl += 'map_Kd ' + str(m[sy.MATERIAL_COLOR_SHADER][sy.BITMAPSHADER_FILENAME]) + '\n'
if(m[sy.MATERIAL_TRANSPARENCY_SHADER]): mtl += 'map_d ' + str(m[sy.MATERIAL_COLOR_SHADER][sy.BITMAPSHADER_FILENAME]) + '\n'
if(m[sy.MATERIAL_BUMP_SHADER]): mtl += 'map_bump ' + str(m[sy.MATERIAL_BUMP_SHADER][sy.BITMAPSHADER_FILENAME]) + '\n'
mtl += 'illum 0\n\n\n'#TODO: setup the illumination, ambient and optical density
mtl = '# Material Count: '+str(mcount)+'\n'+mtl
file = open(mtlPath,'w')
file.write(mtl)
file.close()
It's part of this old script, but note this is with the old R11.5 C4D Python API, the syntax is a bit different now, so use updated documentation and the above more as a general direction on what properties to look for.
A 'codeless' alternative is to bring your model into a different 3D package which properly exports .obj (and .mtl) like Blender for example. You will need to find an intermediary format that will preserve the material data (you can try 3DS,Collada, FBX I think) but be aware of the difference in units and coordinate systems. Hopefully the model features you need are preserved in the file format you export from C4D and properly imported back into the other 3D package.
I have dual head (VGA output, DVI or HDMI output) from 1 PC using this xrandr --output VGA1 --left-of LVDS1. Each having 1024x768 resolution.
When i use this using Java:
screen = Toolkit.getDefaultToolkit().getScreenSize();
I get a huge two screen width together. As a result my Width and height is huge.
Where i only need to place my application in one screen either VGA or DVI. But using Java how do i know that?
How do i tell that using Toolkit.getDefaultToolkit() ?
Example: (my application has to run where Java is labeled)
Test.java
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
public class Test {
public static void main(String[] a) throws Exception {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screenDevices = ge.getScreenDevices();
for (int i = 0; i < screenDevices.length; i++) {
System.out.println(screenDevices[i].getIDstring());
DisplayMode dm = screenDevices[i].getDisplayMode();
int screenWidth = dm.getWidth();
int screenHeight = dm.getHeight();
System.out.println("Cake: " + screenWidth + " " + screenHeight);
}
}
}
Output:
:0.0
Cake: 1024 768
:0.1
Cake: 1024 768
I think
GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()
is what you are looking for. And then from there you can iterate through the screens and get the screen dimension by getDisplayMode()