You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pdfbox.apache.org by Gert van Spijker <ge...@ab-graph.com> on 2012/02/22 22:34:50 UTC
Re: Offer to try to fix the broken "PDPixelMap from BufferedImage"
and some Eclipse questions
Thanks for the hints Andreas,
I actually made already some progress and have a constructor that works,
at least for plain vanilla RGB which is with which I tested.
What I did was use the 1.6 stable jar and created a new implementation
of PDPixelMap within my own package.
I then copied the PDPixelMap source code from the development trunk and
uncommented the broken constructor.
I then modified my calling code, that was up to then was creating a
PDJpeg, to create a PDPixelmap instance and tested.
It actually did produce visible output in the Linux Evince reader that I
use, but it was immediately evident that there was an issue with the
colour space.
It turned out that there are 2 things wrong:
setBitsPerComponent is called erroneously with ColorModel.getPixelSize()
instead of ColorModel.getComponentSize()
so it sets an illegal BitsPerComponent whem an image has more than 1
component.
In case of RGB images the colour channel order is inverse, so the R and
B components have to be swapped.
I have fixed these 2 issues in my version of the constructor and I get
correct RGB images. I did not yet test other image formats and I expect
to find more problems.
It is to early to submit a patch, but here is my version of the
constructor, in case others want to continue with that:
/*
* This fix has only been tested with RGB input so far.
*/
public PDPixelMap(PDDocument doc, BufferedImage awtImage) throws
IOException {
super(doc, "png");
image = awtImage;
setWidth(image.getWidth());
setHeight(image.getHeight());
ColorModel cm = image.getColorModel();
// Use the size of the first channel, which should be the same for all
setBitsPerComponent(cm.getComponentSize(0));
ColorSpace cs = cm.getColorSpace();
PDColorSpace pdColorSpace = PDColorSpaceFactory.createColorSpace(doc, cs);
setColorSpace(pdColorSpace);
PDStream stream = getPDStream();
List<COSName> filters = new ArrayList<COSName>();
filters.add(COSName.FLATE_DECODE);
stream.setFilters(filters);
OutputStream output = null;
try {
output = stream.createOutputStream();
// In case of RGB images we must swap R and B.
if (cm.getNumColorComponents() == 3) {
// Check if we have an alpha channel, which determines whether we have
// to output the fourth byte or not.
boolean hasAlpha = cm.hasAlpha();
int width = getWidth();
int height = getHeight();
int size = width * height;
int[] rgbArray = new int[size];
image.getRGB(0, 0, width, height, rgbArray, 0, width);
for (int n = 0; n < size; n++) {
output.write((byte) (rgbArray[n] >> 16));
output.write((byte) (rgbArray[n] >> 8));
output.write((byte) (rgbArray[n] >> 0));
if(hasAlpha)
output.write((byte) (rgbArray[n] >> 24));
}
} else {
// Not an RGB image so just copy the data buffer for now.
DataBuffer buffer = awtImage.getRaster().getDataBuffer();
if (buffer instanceof DataBufferByte) {
DataBufferByte byteBuffer = (DataBufferByte) buffer;
byte[] data = byteBuffer.getData();
output.write(data);
}
}
} finally {
if (output != null) {
output.close();
}
}
}
Of course I am open to debug and test more and will do anyway, but I
just thought I'd post the intermediate results of my efforts.
Gert
On 22/02/12 18:28, Andreas Lehmkuehler wrote:
> Hi,
>
> sorry for the late answer...
>
> Am 18.02.2012 11:55, schrieb Gert van Spijker:
>> I just signed up for this list, because I would like to start
>> contributing to PDFBox. Actually, I'd like to attack the problem with
>> the broken constructor:
>>
>> PDPixelMap(PDDocument doc, BufferedImage awtImage)
>>
>> In the comment I read: "This method is broken and needs to be
>> implemented, any takers?"
>>
>> My answer to this question is: Yes why not, I'll give it a try..
>>
>> We are using PDFBox in our prepress product, and I'd like to be able to
>> create a lossless image directly from a PDF without having to go through
>> JAI.
> Welcome to our community
>
>> But before I start I have 2 questions:
>>
>> 1: Who is the current developer with the most knowledge about this bug?
>> I'd like to get as much information about the problem as possible.
> We prefer to discuss everything on the dev mailing list, as all
> developers are subscribed to it.
> I guess the problem with the mentioned constructor was, that it simply
> didn't work. If you like to (re)implement it you may consider the following
>
> - read the pdf specs to find out how pixelmaps in pdfs are working
> - have a look at PDPixelMap#getRGBImage, it does the decoding
> - have a look at the implementation of PDJpeg#createImageStream, yours
> maybe similar to it
>
>> 2: I am using Eclipse for development, and checked out trunk through
>> SVN, but when letting it build through Eclipse auto build I stumble
>> across all the missing outside dependencies. I understand that using
>> Maven makes feature selection very simple, but can this be controlled
>> from inside Eclipse? for example by installing the Maven plugin?
>> Does anybody have any experience with building/debugging the PDF core
>> with Eclipse?
> Just install the m2e plugin [1], that should do the trick.
>
> BR
> Andreas Lehmkühler
>
> [1] http://www.eclipse.org/m2e
>
>