Crop and convert to JPG embeeded images
This commit is contained in:
parent
56a815bc9b
commit
93f1aa83d3
4 changed files with 123 additions and 6 deletions
|
@ -25,12 +25,25 @@
|
||||||
|
|
||||||
package w2phtml.base;
|
package w2phtml.base;
|
||||||
|
|
||||||
|
import static w2phtml.office.XMLString.FO_CLIP;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.RasterFormatException;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.apache.commons.imaging.ImageInfo;
|
||||||
|
import org.apache.commons.imaging.ImageReadException;
|
||||||
|
import org.apache.commons.imaging.Imaging;
|
||||||
|
|
||||||
import w2phtml.api.OutputFile;
|
import w2phtml.api.OutputFile;
|
||||||
|
import w2phtml.office.MIMETypes;
|
||||||
import java.io.IOException;
|
import w2phtml.office.StyleWithProperties;
|
||||||
|
import w2phtml.util.DimensionsConverter;
|
||||||
|
|
||||||
/** This class is used to represent a binary graphics document to be included in the converter result.
|
/** This class is used to represent a binary graphics document to be included in the converter result.
|
||||||
* I may also represent a linked image, which should <em>not</em> be included (and will produce an empty file
|
* I may also represent a linked image, which should <em>not</em> be included (and will produce an empty file
|
||||||
|
@ -49,6 +62,9 @@ public class BinaryGraphicsDocument implements OutputFile {
|
||||||
private byte[] blob = null;
|
private byte[] blob = null;
|
||||||
private int nOff = 0;
|
private int nOff = 0;
|
||||||
private int nLen = 0;
|
private int nLen = 0;
|
||||||
|
private boolean cropped = false;
|
||||||
|
private float horizontalPPI = 96.0F;
|
||||||
|
private float verticalPPI = 96.0F;
|
||||||
|
|
||||||
/**Constructs a new graphics document.
|
/**Constructs a new graphics document.
|
||||||
* Until data is added using the <code>read</code> methods, the document is considered a link to
|
* Until data is added using the <code>read</code> methods, the document is considered a link to
|
||||||
|
@ -75,9 +91,27 @@ public class BinaryGraphicsDocument implements OutputFile {
|
||||||
this.blob = bgd.getData();
|
this.blob = bgd.getData();
|
||||||
this.bAcceptedFormat = bgd.isAcceptedFormat();
|
this.bAcceptedFormat = bgd.isAcceptedFormat();
|
||||||
this.bRecycled = true;
|
this.bRecycled = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Is this graphics document recycled?
|
private void extractPPI() {
|
||||||
|
try {
|
||||||
|
ImageInfo info = Imaging.getImageInfo(blob);
|
||||||
|
int heightDPI = info.getPhysicalHeightDpi();
|
||||||
|
if (heightDPI > 0) {
|
||||||
|
this.verticalPPI = heightDPI;
|
||||||
|
}
|
||||||
|
int widthDPI = info.getPhysicalWidthDpi();
|
||||||
|
if (widthDPI > 0) {
|
||||||
|
this.horizontalPPI = widthDPI;
|
||||||
|
}
|
||||||
|
} catch (ImageReadException | IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Is this graphics document recycled?
|
||||||
*
|
*
|
||||||
* @return true if this is the case
|
* @return true if this is the case
|
||||||
*/
|
*/
|
||||||
|
@ -170,8 +204,76 @@ public class BinaryGraphicsDocument implements OutputFile {
|
||||||
public boolean isMasterDocument() {
|
public boolean isMasterDocument() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Does this document contain formulas?
|
public boolean isCropped() {
|
||||||
|
return cropped;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Crop image from byte array */
|
||||||
|
public void cropImage(StyleWithProperties style) {
|
||||||
|
if (blob == null || style == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sMimeType == null || (
|
||||||
|
!sMimeType.equals(MIMETypes.PNG)
|
||||||
|
&& !sMimeType.equals(MIMETypes.JPEG)
|
||||||
|
&& !sMimeType.equals(MIMETypes.GIF)
|
||||||
|
&& !sMimeType.equals(MIMETypes.TIFF)
|
||||||
|
)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
extractPPI();
|
||||||
|
int[] offsets = getOffsets(style);
|
||||||
|
ByteArrayInputStream bis = new ByteArrayInputStream(blob);
|
||||||
|
|
||||||
|
try {
|
||||||
|
BufferedImage image = ImageIO.read(bis);
|
||||||
|
int height = image.getHeight();
|
||||||
|
int width = image.getWidth();
|
||||||
|
String formatName = MIMETypes.getFormatType(blob);
|
||||||
|
int xTopLeft = offsets[3];
|
||||||
|
int yTopLeft = offsets[0];
|
||||||
|
int xBottomRight = width - offsets[3] - offsets[1];
|
||||||
|
int yBottomRight = height - offsets[0] - offsets[2];
|
||||||
|
BufferedImage croppedImage = image.getSubimage(xTopLeft, yTopLeft, xBottomRight , yBottomRight );
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ImageIO.write(croppedImage, "JPG", baos);
|
||||||
|
sMimeType = MIMETypes.JPEG;
|
||||||
|
blob = baos.toByteArray();
|
||||||
|
cropped = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (RasterFormatException e ) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] getOffsets(StyleWithProperties style) {
|
||||||
|
/* top, right, bottom, left */
|
||||||
|
int[] offsets = { 0, 0, 0, 0 };
|
||||||
|
String fo_clip = style.getProperty(FO_CLIP);
|
||||||
|
if (!fo_clip.startsWith("rect(") || !fo_clip.endsWith(")")) {
|
||||||
|
return offsets;
|
||||||
|
}
|
||||||
|
fo_clip = fo_clip.replaceAll("^rect\\(", "");
|
||||||
|
fo_clip = fo_clip.replaceAll("\\)", "");
|
||||||
|
String[] inputOffsets = fo_clip.split("\\s*,\\s*");
|
||||||
|
for (int i = 0; i < inputOffsets.length; i++) {
|
||||||
|
String inputOffset = inputOffsets[i];
|
||||||
|
float ppi;
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
ppi = verticalPPI;
|
||||||
|
} else {
|
||||||
|
ppi = horizontalPPI;
|
||||||
|
}
|
||||||
|
offsets[i] = Math.round(DimensionsConverter.length2px(inputOffset, ppi));
|
||||||
|
}
|
||||||
|
return offsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Does this document contain formulas?
|
||||||
*
|
*
|
||||||
* @return false - a graphics file does not contain formulas
|
* @return false - a graphics file does not contain formulas
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -124,6 +124,18 @@ public final class MIMETypes extends w2phtml.api.MIMETypes {
|
||||||
if (isSVG(blob)) { return SVG; }
|
if (isSVG(blob)) { return SVG; }
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String getFormatType(byte[] blob) {
|
||||||
|
if (isType(blob,PNG_SIG)) { return "PNG"; }
|
||||||
|
if (isType(blob,JPEG_SIG)) { return "JPG"; }
|
||||||
|
if (isType(blob,JPEG_EXIF_SIG)) { return "JPG"; }
|
||||||
|
if (isType(blob,GIF87_SIG)) { return "GIF"; }
|
||||||
|
if (isType(blob,GIF89_SIG)) { return "GIF"; }
|
||||||
|
if (isType(blob,TIFF_SIG)) { return "TIFF"; }
|
||||||
|
if (isType(blob,BMP_SIG)) { return "BMP"; }
|
||||||
|
if (isSVG(blob)) { return "SVG"; }
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String getFileExtension(String sMIME) {
|
public static final String getFileExtension(String sMIME) {
|
||||||
if (PNG.equals(sMIME)) { return PNG_EXT; }
|
if (PNG.equals(sMIME)) { return PNG_EXT; }
|
||||||
|
|
|
@ -434,6 +434,7 @@ public class XMLString {
|
||||||
// fo namespace
|
// fo namespace
|
||||||
public static final String FO_LANGUAGE = "fo:language";
|
public static final String FO_LANGUAGE = "fo:language";
|
||||||
public static final String FO_COUNTRY = "fo:country";
|
public static final String FO_COUNTRY = "fo:country";
|
||||||
|
public static final String FO_CLIP = "fo:clip";
|
||||||
public static final String FO_TEXT_SHADOW = "fo:text-shadow";
|
public static final String FO_TEXT_SHADOW = "fo:text-shadow";
|
||||||
public static final String FO_COLOR = "fo:color";
|
public static final String FO_COLOR = "fo:color";
|
||||||
public static final String FO_BACKGROUND_COLOR = "fo:background-color";
|
public static final String FO_BACKGROUND_COLOR = "fo:background-color";
|
||||||
|
|
|
@ -539,6 +539,8 @@ public class DrawParser extends Parser {
|
||||||
String sFileName = null;
|
String sFileName = null;
|
||||||
bgd = converter.getImageCv().getImage(onode);
|
bgd = converter.getImageCv().getImage(onode);
|
||||||
if (bgd!=null) {
|
if (bgd!=null) {
|
||||||
|
StyleWithProperties style = ofr.getFrameStyle(frame.getAttribute(XMLString.DRAW_STYLE_NAME));
|
||||||
|
bgd.cropImage(style);
|
||||||
if (!bgd.isLinked()) { // embedded image
|
if (!bgd.isLinked()) { // embedded image
|
||||||
sFileName = bgd.getFileName();
|
sFileName = bgd.getFileName();
|
||||||
// If this is the cover image, add it to the converter result
|
// If this is the cover image, add it to the converter result
|
||||||
|
|
Loading…
Add table
Reference in a new issue