[ 
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)

Reply via email to