RED-2414
Wrong scaling for Images in Reports
This commit is contained in:
parent
f258d62a1f
commit
599a099d35
@ -1,5 +1,48 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.DOSSIER_NAME_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.EXCERPT_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FILE_NAME_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ENG;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ENG_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_GER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_GER_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ISO;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ISO_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_TIME_ISO;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_TIME_ISO_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.JUSTIFICATION_PARAGRAPH_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.JUSTIFICATION_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.JUSTIFICATION_REASON_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.PAGE_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.PARAGRAPH_PLACEHOLDER;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.poi.ss.usermodel.CreationHelper;
|
||||
import org.apache.poi.ss.usermodel.Drawing;
|
||||
import org.apache.poi.ss.usermodel.Picture;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierAttributeConfig;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.Dossier;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierAttribute;
|
||||
@ -10,29 +53,10 @@ import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributes
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesConfigClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ImagePlaceholder;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.util.Dimension2DDouble;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -240,30 +264,29 @@ public class ExcelTemplateReportGenerationService {
|
||||
if (cell.getStringCellValue().contains(imagePlaceholder.getPlaceholder())) {
|
||||
try (ByteArrayInputStream is = new ByteArrayInputStream(imagePlaceholder.getImage())) {
|
||||
|
||||
ByteArrayInputStream scaledImage = getScaledImage(is, sheet.getColumnWidthInPixels(cell.getColumnIndex()), convertPointsToPixel(cell.getRow().getHeightInPoints()));
|
||||
// ByteArrayInputStream scaledImage = getScaledImage(is, PixelUtil.widthUnits2Pixel((short) sheet.getColumnWidth(cell.getColumnIndex())), PixelUtil.heightUnits2Pixel(cell.getRow().getHeight()));
|
||||
// is.reset();
|
||||
|
||||
double factor = calculateScale(is, PixelUtil.widthUnits2Pixel((short) sheet.getColumnWidth(cell.getColumnIndex())), PixelUtil.heightUnits2Pixel(cell.getRow().getHeight()));
|
||||
is.reset();
|
||||
|
||||
int pictureIdx = workbook.addPicture(scaledImage, XSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
// scaledImage.reset();
|
||||
int pictureIdx = workbook.addPicture(is, XSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
is.reset();
|
||||
|
||||
//Returns an object that handles instantiating concrete classes
|
||||
CreationHelper helper = workbook.getCreationHelper();
|
||||
//Creates the top-level drawing patriarch.
|
||||
//Create an anchor that is attached to the worksheet
|
||||
ClientAnchor anchor = helper.createClientAnchor();
|
||||
// anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
|
||||
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
|
||||
|
||||
anchor.setCol1(cell.getColumnIndex());
|
||||
anchor.setRow1(cell.getRowIndex());
|
||||
anchor.setCol2(cell.getColumnIndex() + 1);
|
||||
anchor.setRow2(cell.getRowIndex() + 1);
|
||||
|
||||
//Creates the top-level drawing patriarch.
|
||||
Drawing drawing = sheet.createDrawingPatriarch();
|
||||
drawing.createPicture(anchor, pictureIdx);
|
||||
|
||||
//sheet.setColumnWidth(cell.getColumnIndex(), (int) dim.getWidth());
|
||||
|
||||
// cell.getRow().setHeight((short) dim.getHeight());
|
||||
Picture picture = drawing.createPicture(anchor, pictureIdx);
|
||||
picture.resize(factor);
|
||||
|
||||
cell.setCellValue("");
|
||||
}
|
||||
@ -273,138 +296,26 @@ public class ExcelTemplateReportGenerationService {
|
||||
}
|
||||
|
||||
|
||||
private float convertPointsToPixel(float points) {
|
||||
return points/0.75f;
|
||||
}
|
||||
private double calculateScale(ByteArrayInputStream imageByteArrayInputStream, float cellWidth, float cellHeight) throws IOException {
|
||||
BufferedImage img = ImageIO.read(imageByteArrayInputStream);
|
||||
|
||||
double imageWidth = img.getWidth();
|
||||
double imageHeight = img.getHeight();
|
||||
|
||||
private ByteArrayInputStream getScaledImage(ByteArrayInputStream imageByteArrayInputStream, float cellWidth, float cellHeight) throws IOException {
|
||||
BufferedImage image = ImageIO.read(imageByteArrayInputStream);
|
||||
|
||||
double imageWidth = image.getWidth();
|
||||
double imageHeight = image.getHeight();
|
||||
|
||||
double imageWidthScaleFactor;
|
||||
double imageHeightScaleFactor;
|
||||
|
||||
double imageRatio = imageWidth/imageHeight;
|
||||
|
||||
// if(cellRatio <= 1 && imageRatio <=1) {
|
||||
// // cell and image are landscape
|
||||
//
|
||||
//
|
||||
// } else if(cellRatio <= 1 && imageRatio <=1) {
|
||||
// // cell and image are portrait
|
||||
//
|
||||
// } else if(cellRatio <= 1 && imageRatio <=1) {
|
||||
// // cell is landscape and image is portrait
|
||||
//
|
||||
// } else if(cellRatio <= 1 && imageRatio <=1) {
|
||||
// // cell is portrait and image is landscape
|
||||
//
|
||||
// }
|
||||
|
||||
AffineTransform at = new AffineTransform();
|
||||
|
||||
imageWidthScaleFactor = cellWidth / imageWidth;
|
||||
imageHeightScaleFactor = cellHeight / imageHeight;
|
||||
|
||||
if(imageWidthScaleFactor <= 1 && imageHeightScaleFactor > 1) {
|
||||
imageWidth = imageWidth * imageWidthScaleFactor;
|
||||
imageHeight = imageHeight * imageWidthScaleFactor;
|
||||
|
||||
at.scale(imageWidthScaleFactor, imageRatio);
|
||||
|
||||
} else if(imageWidthScaleFactor > 1 && imageHeightScaleFactor <= 1) {
|
||||
imageHeight = imageHeight * imageHeightScaleFactor;
|
||||
imageWidth = imageWidth * imageHeightScaleFactor;
|
||||
|
||||
at.scale(imageHeightScaleFactor, imageHeightScaleFactor/imageWidthScaleFactor);
|
||||
|
||||
} else if(imageWidthScaleFactor <= 1 && imageHeightScaleFactor <= 1) {
|
||||
if(imageWidthScaleFactor <= imageHeightScaleFactor) {
|
||||
imageWidth = imageWidth * imageWidthScaleFactor;
|
||||
imageHeight = imageHeight * imageWidthScaleFactor;
|
||||
|
||||
at.scale(imageWidthScaleFactor, imageWidthScaleFactor/imageHeightScaleFactor);
|
||||
} else {
|
||||
imageHeight = imageHeight * imageHeightScaleFactor;
|
||||
imageWidth = imageWidth * imageHeightScaleFactor;
|
||||
|
||||
at.scale(imageHeightScaleFactor, imageHeightScaleFactor/imageWidthScaleFactor);
|
||||
}
|
||||
double widthFactor = (double) cellWidth/ imageWidth;
|
||||
double heightFactor = (double) cellHeight/ imageHeight;
|
||||
|
||||
if (imageWidth < cellWidth && imageHeight < cellHeight) {
|
||||
return 1;
|
||||
} else if (cellWidth > cellHeight) {
|
||||
return heightFactor;
|
||||
} else {
|
||||
at.scale(1/imageHeightScaleFactor, 1/imageWidthScaleFactor);
|
||||
return widthFactor;
|
||||
}
|
||||
|
||||
// AffineTransform at = new AffineTransform();
|
||||
// at.scale(1/imageWidthScaleFactor, 1/imageHeightScaleFactor);
|
||||
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
|
||||
BufferedImage scaledImage = new BufferedImage((int) imageWidth, (int) imageHeight, image.getType());
|
||||
scaledImage = scaleOp.filter(image, scaledImage);
|
||||
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
ImageIO.write(scaledImage, "jpeg", os);
|
||||
//os.reset();
|
||||
return new ByteArrayInputStream(os.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// private ByteArrayInputStream getScaledImage(ByteArrayInputStream imageByteArrayInputStream, float cellWidth, float cellHeight) throws IOException {
|
||||
// BufferedImage image = ImageIO.read(imageByteArrayInputStream);
|
||||
//
|
||||
// double imageWidth = image.getWidth();
|
||||
//
|
||||
// double imageHeight = image.getHeight();
|
||||
//
|
||||
// double cellRatio = cellWidth/cellHeight;
|
||||
// double imageRatio = imageWidth/imageHeight;
|
||||
//
|
||||
// boolean scaleWidth = imageWidth > cellWidth;
|
||||
// boolean scaleHeight = imageHeight > cellHeight;
|
||||
//
|
||||
// double imageWidthScaleFactor;
|
||||
// double imageHeightScaleFactor;
|
||||
//
|
||||
// if (scaleWidth && scaleHeight) {
|
||||
// // image width and height is greater than cell
|
||||
// if (imageRatio < cellRatio) {
|
||||
// // scale width
|
||||
// imageWidthScaleFactor = cellWidth / imageWidth;
|
||||
// imageHeightScaleFactor = imageWidthScaleFactor / imageRatio;
|
||||
// } else {
|
||||
// // scale height
|
||||
// imageHeightScaleFactor = cellHeight / imageHeight;
|
||||
// imageWidthScaleFactor = imageHeightScaleFactor * imageRatio;
|
||||
// }
|
||||
// } else if (scaleWidth) {
|
||||
// // only image width is greater than cell
|
||||
// imageWidthScaleFactor = cellWidth / imageWidth;
|
||||
// imageHeightScaleFactor = imageWidthScaleFactor / imageRatio;
|
||||
// } else if (scaleHeight) {
|
||||
// // only image height is greater than cell
|
||||
// imageHeightScaleFactor = cellHeight / imageHeight;
|
||||
// imageWidthScaleFactor = imageHeightScaleFactor * imageRatio;
|
||||
// } else {
|
||||
// // nothing to do, image fits in cell
|
||||
// imageWidthScaleFactor = 1;
|
||||
// imageHeightScaleFactor = 1;
|
||||
// }
|
||||
//
|
||||
// AffineTransform at = new AffineTransform();
|
||||
// at.scale(imageWidthScaleFactor, imageHeightScaleFactor);
|
||||
// AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
|
||||
// BufferedImage scaledImage = new BufferedImage((int) (imageWidth * imageWidthScaleFactor), (int) (imageHeight * imageHeightScaleFactor), image.getType());
|
||||
// scaledImage = scaleOp.filter(image, scaledImage);
|
||||
//
|
||||
// ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
// ImageIO.write(scaledImage, "jpeg", os);
|
||||
// //os.reset();
|
||||
// return new ByteArrayInputStream(os.toByteArray());
|
||||
// }
|
||||
//
|
||||
private String getPlaceholderValue(String placeholder, Dossier project, FileModel fileStatus,
|
||||
Map<String, String> fileAttributePlaceholders,
|
||||
Map<String, String> dossierAttributesPlaceholders) {
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
public class PixelUtil {
|
||||
|
||||
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
||||
public static final short EXCEL_ROW_HEIGHT_FACTOR = 20;
|
||||
public static final int UNIT_OFFSET_LENGTH = 7;
|
||||
public static final int[] UNIT_OFFSET_MAP = new int[] { 0, 36, 73, 109, 146, 182, 219 };
|
||||
|
||||
public static short pixel2WidthUnits(int pxs) {
|
||||
short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * (pxs / UNIT_OFFSET_LENGTH));
|
||||
widthUnits += UNIT_OFFSET_MAP[pxs % UNIT_OFFSET_LENGTH];
|
||||
return widthUnits;
|
||||
}
|
||||
|
||||
public static int widthUnits2Pixel(short widthUnits) {
|
||||
int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) * UNIT_OFFSET_LENGTH;
|
||||
int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR;
|
||||
pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH));
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public static int heightUnits2Pixel(short heightUnits) {
|
||||
int pixels = heightUnits / EXCEL_ROW_HEIGHT_FACTOR;
|
||||
int offsetWidthUnits = heightUnits % EXCEL_ROW_HEIGHT_FACTOR;
|
||||
pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_ROW_HEIGHT_FACTOR / UNIT_OFFSET_LENGTH));
|
||||
return pixels;
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,6 @@ import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@ -34,12 +33,10 @@ import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.Re
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.Dossier;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierAttribute;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierAttributeType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileAttribute;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileAttributeConfig;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileAttributeType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.legalbasis.LegalBasis;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.legalbasis.LegalBasisMapping;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.ReportType;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributesClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributesConfigClient;
|
||||
@ -412,11 +409,11 @@ public class RedactionReportIntegrationTest {
|
||||
public void testIuclidReport() {
|
||||
String dossierTemplateId = "dossierTemplateId";
|
||||
|
||||
ClassPathResource redactionLogResource = new ClassPathResource("files/redactionLog.json");
|
||||
ClassPathResource redactionLogResource = new ClassPathResource("files/S11RedactionLog.json");
|
||||
|
||||
RedactionLog redactionLog = objectMapper.readValue(redactionLogResource.getInputStream(), RedactionLog.class);
|
||||
|
||||
ClassPathResource legalBasisMappingResource = new ClassPathResource("files/legalBasisMapping.json");
|
||||
ClassPathResource legalBasisMappingResource = new ClassPathResource("files/S1116LegalBasis.json");
|
||||
|
||||
List<LegalBasis> legalBasisMapping = objectMapper.readValue(legalBasisMappingResource.getInputStream(), new TypeReference<>() {
|
||||
});
|
||||
@ -433,7 +430,7 @@ public class RedactionReportIntegrationTest {
|
||||
when(fileAttributesConfigClient.getFileAttributeConfigs(dossierTemplateId)).thenReturn(new ArrayList<>());
|
||||
|
||||
|
||||
FileModel fileStatus = FileModel.builder().filename("filename").build();
|
||||
FileModel fileStatus = FileModel.builder().filename("VV123456").build();
|
||||
|
||||
Dossier project = Dossier.builder().id("dossierId").dossierName("projectName").build();
|
||||
|
||||
@ -455,7 +452,7 @@ public class RedactionReportIntegrationTest {
|
||||
.build();
|
||||
byte[] report = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE, reportEntries, dossierTemplateId, reportTemplate, fileStatus, project);
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/iuclid_report.docx")) {
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/iuclid_report_2.docx")) {
|
||||
fileOutputStream.write(report);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user