[ https://issues.apache.org/jira/browse/PDFBOX-1915?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14011885#comment-14011885 ]
Shaola Ren commented on PDFBOX-1915: ------------------------------------ an even older stuff the reading data part is almost done the code are available at https://bitbucket.org/xinshu/pdfbox.git for webview https://bitbucket.org/xinshu/pdfbox This is stuff edited from the emails from me and Tilman, I am sorry that I didn't post my questions on Jira earlier, hopefully these emails don't have any thing that is not suitable to be published publicly, if there are such issues, Tilman Please, Feel free to delete or edit them. I am sorry for this unconvenience. related file is Shadingtype6week1.pdf May 23 >From Shaola to Tilman Hello Tilman, I modified the shading package, and the code are available at https://bitbucket.org/xinshu/pdfbox.git, midway done, may have bugs. However, It’s better to summarize the progress made in this week and talk to you to get some feedback. Any suggestion is appreciated, take you time. I encountered some questions which I put in this powerpoint(attached) and highlighted by blue color. If these questions are too vague, you don’t need to give an explicit answer. Thanks! >From Tilman to Shaola Quick answer - to use LOG.debug() you must set debug level. This is done in the file "log4j.properties" in the default package of your application. Alternatively, use LOG.info() and it should work immediately (with the command line utility) Here's a sample log4j file with debug level enabled: log4j.rootLogger=DEBUG, A1 #log4j.rootLogger=INFO, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss.SSS} %-5p [%t] %C:%L - %m%n System.out.println() is the quick way, but you should get used to use "apache log4j". Download it at https://logging.apache.org/log4j/1.2/ and attach it to your calling application. Yes, it takes that long to build. You could probably write a script to copy the class file that is created while editing and insert it to an existing jar file. I assume you could also skip the tests. I just tested this :-) https://maven.apache.org/surefire/maven-surefire-plugin/examples/skipping-test.html just add -DskipTests Hello Shaola, /ShadingType 6 /ColorSpace/DeviceRGB /Decode[-16384 16384 -16384 16384 0 1 0 1 0 1] /BitsPerCoordinate 24 /BitsPerComponent 16 /BitsPerFlag 8 BitsPerCoordinate = 24, it means that the max value in the stream for a coordinate is 0xFFFFFF = 16777215. This is then mapped to the target which has an interval [-16384..16384] with "interpolate". The values you get must then be "transformed" into the physical coordinates, which is done in GouraudShadingContext.transformVertices(). You can probably reuse this. At first, just make yourself a copy; later in the project, it should possibly be merged so that no code exists twice. https://en.wikipedia.org/wiki/Don%27t_repeat_yourself Re "transform", this is two things: 1) PDF related transformations, i.e. mentioned in the PDF 2) java graphics transform: depends on the size of the image. Usually this is a scale, 4.16 for 300dpi. I don't see that you did the transform, which may explain why you get such weird coordinates... and yes, after the transforms, you get physical coords. Look at Gouraud shading, the transform is done at the beginning only, i.e. only once. In getRaster(), you then work with "real, screen" coordinates. I don't think it is useful to generate the points separately, as they are painted only once. The raster in which the other shading classes are writing into is a "Table", somehow. Some people render at 300dpi. An A4 page is about 2500 x 3500 pixels. Re getraster(): yes, getraster only paints a small section. It is called again and again and again. X and Y are physical pixels. I strongly recommend to first "get something simple that works". Even if slow. From there, you can try to make changes, and if these go wrong, you can always go back to the "simple" solution. Hint: output the "raw" coordinates and the interval boundaries in hex. This is done with System.out.println (String.format("%x", val)). This gives you a better idea of the relationships between the numbers. Minor thing: getParamSpaceColor(int i, int j) are these coordinates? If yes, please name them x and y. Same for getPatchCoordinates. I hope I answered most, if not all. Good luck! >From Shaola to Tilman 2) java graphics transform: depends on the size of the image. Usually this is a scale, 4.16 for 300dpi. I don't see that you did the transform, which may explain why you get such weird coordinates... and yes, after the transforms, you get physical coords. I will check this, as the transform matrix is optional, I just doubted this but didn't test. Look at Gouraud shading, the transform is done at the beginning only, i.e. only once. In getRaster(), you then work with "real, screen" coordinates. I don't think it is useful to generate the points separately, as they are painted only once. The raster in which the other shading classes are writing into is a "Table", somehow. Some people render at 300dpi. An A4 page is about 2500 x 3500 pixels. This information is useful, it prevents me to think more in this direction. I strongly recommend to first "get something simple that works". Even if slow. From there, you can try to make changes, and if these go wrong, you can always go back to the "simple" solution. I will. Minor thing: getParamSpaceColor(int i, int j) are these coordinates? If yes, please name them x and y. Same for getPatchCoordinates. These are not real coordinates, as before getting real coordinates, cubic Bezier curve needs an assistant parameter to get its points position, the returned value of getPatchCoordinates() is real coordinate, similar to getParamSpaceColor, that is the mapping step. However, I don't need to generate all the point separately as you said, I have to think it in other way as you did in the GouraudShadingContext to check whether a specific point is inside an image and rewrite these methods. I hope I answered most, if not all. Thanks for you quick, useful and exhaustive response. The coordinate problem is solved, I need to apply the transform, thanks. The method to accomplish getRaster() should be different from what I thought before, please see the attachment. If there is anything wrong obviously, please remind me. >From Tilman to Shaola Hi Shaola, Yes it is tricky to think this in reverse; there's a similar problem in the Radial Shading, the developer who did this had to solve an equation. (There's a long comment in the code about that) >From Shaola to Tilman Thanks for mentioning the radial shading. 1. I would use the sub-dividing method to judge whether a point is below or above a cubic Bezier curve, then combining the results of 4 curves to decide whether a point is inside or out of a patch, this works in a O(lg(n)) time complexity, which should be good enough. 2. to solve the possible points, in the radial shading case, that equation has an analytic solution, in this shading type 6 case, only one equation and the equation has two unknowns with boundaries, the highest order is 4, there is no analytic solution. I will try to solve the equation numerically. Best, Shaola > Implement shading with Coons and tensor-product patch meshes > ------------------------------------------------------------ > > Key: PDFBOX-1915 > URL: https://issues.apache.org/jira/browse/PDFBOX-1915 > Project: PDFBox > Issue Type: Improvement > Components: Rendering > Affects Versions: 2.0.0 > Reporter: Tilman Hausherr > Labels: graphical, gsoc2014, java, math, shading > Attachments: CONICAL.pdf, GWG060_Shading_x1a.pdf, HSBWHEEL.pdf, > McAfee-ShadingType7.pdf, TENSOR.pdf, XYZsweep.pdf, > asy-coons-but-really-tensor.pdf, asy-tensor-rainbow.pdf, asy-tensor.pdf, > coons-function.pdf, coons-function.ps, coons-nofunction-CMYK.pdf, > coons-nofunction-CMYK.ps, coons-nofunction-Duotone.pdf, > coons-nofunction-Duotone.ps, coons-nofunction-Gray.pdf, > coons-nofunction-Gray.ps, coons-nofunction-RGB.pdf, coons-nofunction-RGB.ps, > coons2-function.pdf, coons2-function.ps, > eci_altona-test-suite-v2_technical_H.pdf, lamp_cairo.pdf > > > Of the seven shading methods described in the PDF specification, type 6 > (Coons patch meshes) and type 7 (Tensor-product patch meshes) haven't been > implemented. I have done type 1, 4 and 5, but I don't know the math for type > 6 and 7. My math days are decades away. > Knowledge prerequisites: > - java, although you don't have to be a java ace, just feel confortable > - math: you should know what "cubic Bézier curves", "Degenerate Bézier > curves", "bilinear interpolation", "tensor-product", "affine transform > matrix" and "Bernstein polynomials" are, or be able to learn it > - maven (basic) > - svn (basic) > - an IDE like Netbeans or Eclipse or IntelliJ (basic) > - ideally, you are either a math student who likes to program, or a computer > science student who is specializing in graphics. > A first look at PDFBOX: try the command utility here: > https://pdfbox.apache.org/commandline/#pdfToImage > and use your favorite PDF, or the PDFs mentioned in PDFBOX-615, these have > the shading types that are already implemented. > Some simple source code to convert to images: > String filename = "blah.pdf"; > PDDocument document = PDDocument.loadNonSeq(new File(filename), null); > List<PDPage> pdPages = document.getDocumentCatalog().getAllPages(); > int page = 0; > for (PDPage pdPage : pdPages) > { > ++page; > BufferedImage bim = RenderUtil.convertToImage(pdPage, > BufferedImage.TYPE_BYTE_BINARY, 300); > ImageIO.write(bim, "png", new File(filename+page+".png")); > } > document.close(); > You are not starting from scratch. The implementation of type 4 and 5 shows > you how to read parameters from the PDF and set the graphics. You don't have > to learn the complete PDF spec, only 15 pages related to the two shading > types, and 6 pages about shading in general. The PDF specification is here: > http://www.adobe.com/devnet/pdf/pdf_reference.html > The tricky parts are: > - decide whether a point(x,y) is inside or outside a patch > - decide the color of a point within the patch > To get an idea about the code, look at the classes GouraudTriangle, > GouraudShadingContext, Type4ShadingContext and Vertex here > https://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/ > or download the whole project from the repository. > https://pdfbox.apache.org/downloads.html#scm > If you want to see the existing code in the debugger with a Gouraud shading, > try this file: > http://asymptote.sourceforge.net/gallery/Gouraud.pdf > Testing: > I have attached several example PDFs. To see which one has which shading, > open them with an editor like NOTEPAD++, and search for "/ShadingType" > (without the quotes). If your images are rendering like the example PDFs, > then you were successful. > Optional: > Review and optimize the complete shading package for speed; implement cubic > spline interpolation for type 0 (sampled) functions (that one is really > low-low priority, see details by looking up "cubic spline interpolation" in > the PDF spec, which tells that it is disregarded in printing, and I don't > have a test PDF). > Mentor: Tilman Hausherr (European timezone, languages: german, english, > french) -- This message was sent by Atlassian JIRA (v6.2#6252)