package bd.amazed.docscissors.doc;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.ProgressMonitor;
import org.apache.commons.io.FilenameUtils;
import org.rr.commons.mufs.IResourceHandler;
import org.rr.commons.mufs.ResourceHandlerFactory;
import org.rr.commons.utils.compression.truezip.TrueZipUtils;
import org.rr.jeborker.metadata.MetadataUtils;
import org.rr.jeborker.metadata.comicbook.ArchiveHandlerFactory;
import org.rr.jeborker.metadata.comicbook.ComicBookDocument;
import org.rr.jeborker.metadata.comicbook.ComicBookPageInfo;
import org.rr.jeborker.metadata.comicbook.ComicBookReader;
import org.rr.jeborker.metadata.comicbook.IArchiveHandler;
import org.rr.pm.image.IImageProvider;
import org.rr.pm.image.ImageInfo;
import org.rr.pm.image.ImageProviderFactory;
import org.rr.pm.image.ImageUtils;
import bd.amazed.docscissors.model.PageRectsMap;
import com.itextpdf.text.DocumentException;
/**
* Cropper for CBZ and CBR
*/
public class CbxCropper extends DocumentCropper {
public CbxCropper(IResourceHandler file) {
super(file);
}
private static Rectangle getMaxBoundingBox(ComicBookReader reader) throws IOException {
Rectangle maxBoundingBox = new Rectangle(0, 0, 0, 0);
List<ComicBookPageInfo> pages = reader.getDocument().getPages();
if(pages.isEmpty()) {
IArchiveHandler archiveHandler = reader.getArchiveHandler();
List<String> archiveEntries = archiveHandler.getArchiveEntries();
for (String archiveEntry : archiveEntries) {
byte[] imageBytes = archiveHandler.getArchiveEntry(archiveEntry);
IImageProvider imageProvider = ImageProviderFactory.getImageProvider(ResourceHandlerFactory.getVirtualResourceHandler(archiveEntry, imageBytes));
ImageInfo imageInfo = imageProvider.getImageInfo();
maxBoundingBox.width = Math.max(imageInfo.getWidth(), maxBoundingBox.width);
maxBoundingBox.height = Math.max(imageInfo.getHeight(), maxBoundingBox.height);
}
} else {
for (ComicBookPageInfo page : pages) {
int height = page.getImageHeight();
int width = page.getImageWidth();
maxBoundingBox.width = Math.max(width, maxBoundingBox.width);
maxBoundingBox.height = Math.max(height, maxBoundingBox.height);
}
}
return maxBoundingBox;
}
@Override
public void cancel() {
isCancel = true;
}
@Override
public void crop(DocumentInfo docInfo, File targetFile, PageRectsMap pageRectsMap, int viewWidth, int viewHeight, ProgressMonitor progressMonitor)
throws IOException, DocumentException {
IResourceHandler targetResourceHandler = ResourceHandlerFactory.getResourceHandler(targetFile);
IArchiveHandler targetArchiveHandler = ArchiveHandlerFactory.getHandler(targetResourceHandler);
ComicBookReader reader = new ComicBookReader(docInfo.getOriginalFile());
ComicBookDocument doc = reader.getDocument();
List<String> imageNames = doc.getImageNames();
Set<String> usedImageNames = new HashSet<>();
for(int i = 0; i < imageNames.size(); i++) {
String imageName = imageNames.get(i);
byte[] imageBytes = reader.getArchiveHandler().getArchiveEntry(imageName);
IImageProvider imageProvider = ImageProviderFactory.getImageProvider(ResourceHandlerFactory.getVirtualResourceHandler(imageName, imageBytes));
BufferedImage image = imageProvider.getImage();
pageRectsMap.setOriantationMode(PageRectsMap.ORIENTATION_Y_TOP);
ArrayList<Rectangle> cropRectsInIPDFCoords = pageRectsMap.getConvertedRectsForCropping(i + 1, viewWidth, viewHeight, docInfo.getNormalizedWidth(), docInfo.getNormalizedHeight());
addImageNameWhenUsed(usedImageNames, imageName, cropRectsInIPDFCoords);
for(Rectangle cropRectsInIPDFCoord : cropRectsInIPDFCoords) {
BufferedImage copedImage = ImageUtils.crop(image, cropRectsInIPDFCoord, Color.WHITE);
byte[] expandedImageBytes = ImageUtils.getImageBytes(copedImage, imageProvider.getImageInfo().getMimeType());
String targetImageName = imageName;
for(int j = 0; usedImageNames.contains(targetImageName); j++) {
targetImageName = FilenameUtils.removeExtension(imageName) + "_" + j + "." + FilenameUtils.getExtension(imageName);
}
usedImageNames.add(targetImageName);
targetArchiveHandler.addArchiveEntry(targetImageName, expandedImageBytes);
}
}
TrueZipUtils.unmout();
MetadataUtils.copyMetadata(docInfo.getOriginalFile(), targetResourceHandler);
}
private void addImageNameWhenUsed(Set<String> usedImageNames, String imageName, ArrayList<Rectangle> cropRectsInIDocCoords) {
boolean multiplePages = cropRectsInIDocCoords.size() > 1;
if(multiplePages) {
usedImageNames.add(imageName); //mark the current name as used when having multiple rectangles on the page
}
}
@Override
public DocumentInfo getDocumentInfo() throws DocumentException, IOException {
ComicBookReader reader = new ComicBookReader(mainFile);
ComicBookDocument doc = reader.getDocument();
Rectangle maxBoundingBox = getMaxBoundingBox(reader);
DocumentInfo docFile = new DocumentInfo(mainFile, mainFile, doc.getCount());
docFile.setDocInfo(doc.getInfo());
docFile.setPageCount(doc.getCount());
docFile.setNormalizedWidth(Math.abs((float)maxBoundingBox.getWidth()));
docFile.setNormalizedHeight(Math.abs((float)maxBoundingBox.getHeight()));
return docFile;
}
}