I am inserting image in using this
var readFileIntoDataUrl = function (fileInfo) {
var loader = $.Deferred(),
fReader = new FileReader();
fReader.onload = function (e) {
loader.resolve(e.target.result);
};
fReader.onerror = loader.reject;
fReader.onprogress = loader.notify;
fReader.readAsDataURL(fileInfo);
return loader.promise();
};
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
execCommand('insertimage', dataUrl);
}).fail(function (e) {
options.fileUploadError("file-reader", e);
});
Let say i added a text Hello World and added a image. Now when i take $("#editor").html() it shows something like below
Here is a sample source of a image+text
Hello World!
img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoRXhpZgAATU0AKgAAAAgA
BAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAAAABgAAAA
AQAAAGAAAAABUGFpbnQuTkVUIHYzLjUuOAAA/9sAQwAHBQUGBQQHBgUGCAcHCAoRCwoJCQoVDxAMERgV
[... more base64 data here....]
Now here i have both text+image So both on server side and client side i want to resize & compress image
So that no one can insert image > 5MP and also keep a rich text with resize image in my db
This is how you can do it on the server side (Java):
String imageData = "Hello World! img src=\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoR...";
//Image data starting point
int startIndex = imageData.indexOf(";base64,") + ";base64,".length();
//keep only the image data
imageData = imageData.substring(startIndex, imageData.length());
//convert the image data String to a byte[]
byte[] dta = DatatypeConverter.parseBase64Binary(imageData);
try (InputStream in = new ByteArrayInputStream(dta);) {
BufferedImage fullSize = ImageIO.read(in);
// Create a new image half the size of the original image
BufferedImage resized = new BufferedImage(fullSize.getWidth() / 2, fullSize.getHeight() / 2, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = (Graphics2D) resized.getGraphics();
g2.drawImage(fullSize, 0, 0, resized.getWidth(), resized.getHeight(), 0, 0, fullSize.getWidth(), fullSize.getHeight(), null);
g2.dispose();
} catch (IOException e) {
e.printStackTrace();
}
As for the JavaScript part you can use a canvas, size the canvas to the dimension that you want, draw your image on it and use the toDataURL method to convert the image to a String
Related
I'm trying to store an imageIcon bas a Base64 String.
This is what I have so far:
public ImageIcon getImageIcon() {
if(imageIcon == null || imageIcon.isEmpty()){
return null;
} else {
try {
byte[] btDataFile = Base64.decodeBase64(imageIcon);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(btDataFile));
return new ImageIcon(image);
} catch (IOException ex) {
System.out.println(ex.getLocalizedMessage());
return null;
}
}
}
public void setImageIcon(ImageIcon imageIconIn) {
imageIcon = Base64.encodeBase64String(imageToByteArray(imageIconIn));
}
public static byte[] imageToByteArray(ImageIcon imageIn) {
try {
BufferedImage image = new BufferedImage(imageIn.getIconWidth(), imageIn.getIconHeight(),BufferedImage.TYPE_INT_RGB);
ByteArrayOutputStream b = new ByteArrayOutputStream();
// FIX
Graphics g;
g = image.createGraphics();
imageIn.paintIcon(null, g, 0,0);
// END FIX
ImageIO.write(image, "jpg", b );
g.dispose();
return b.toByteArray();
} catch (IOException ex) {
System.out.println(ex.getLocalizedMessage());
return null;
}
}
I get a black rectangle instead of the image.
I'm using Java 1.8 on Ubuntu 16.04.
What am I doing wrong?
Thanks for your help.
******************************** . FIXED . ******************************
I found a working solution and updated the above code.
******************************** EDIT *********************************
Added g.dispose() after painting icon.
This code creates a brand new BufferedImage, with width & height same as the given image.
BufferedImage image = new BufferedImage(
imageIn.getIconWidth(),
imageIn.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Note that the image is empty. No content has been written to it. The bytes will all be zero, and RGB 0x000000 is black.
Then, you are writing the bytes of this black image to your ByteArrayOutputStream.
ByteArrayOutputStream b = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", b );
return b.toByteArray();
Of course, when you convert that byte buffer back to an image, it will be black.
You will want to draw/copy imageIn into your new image before you write out the bytes.
But if you don't mind using whatever the current image's format is, you could just write out that image instead of converting it to TYPE_INT_RGB...
Image image = imageIn.getImage();
// write image to ByteArrayOutputStream
I am trying to merge two TIFF images which are in form of FileInputStream into a single Tiff image. Although the image is getting merged the output file is coming up as Black. While comparing the original image and the converted image I could see that the bit depth of the converted image changes to 1. Could anybody provide a solution to this?
The code that I am using is:
public class MergerTiffUsingBuffer {
public static void main(String[] args) {
File imageFile1 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/FLAG_T24.TIF");
File imageFile2 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/CCITT_3.TIF");
try {
FileInputStream fis1 = new FileInputStream(imageFile1);
FileInputStream fis2 = new FileInputStream(imageFile2);
List<BufferedImage> bufferedImages=new ArrayList<>();
List<FileInputStream> inputStreams=new ArrayList<>();
inputStreams.add(fis1);
inputStreams.add(fis2);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("tiff");
ImageReader reader = (ImageReader) readers.next();
for(FileInputStream inputStream:inputStreams){
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
BufferedImage binarized = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),BufferedImage.TYPE_BYTE_BINARY);
ImageIO.write(binarized, "tiff", out);
bufferedImages.add(bufferedImage);
}
System.out.println(bufferedImages.size());
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
You seem to be a little confused about how to copy image data. Simply creating a new, blank image, by passing the dimensions of another image, will not copy it... So a fully black image is what I would expect after running your code.
Replace your for loop with something like this:
for (FileInputStream inputStream : inputStreams) {
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
BufferedImage image = reader.read(0, null); // a) BufferedImage is returned! b) null param is fine!
BufferedImage binarized = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
// The following 7 lines is the important part you were missing:
Graphics2D g = binarized.createGraphics();
try {
g.drawImage(image, 0, 0, null);
}
finally {
g.dispose();
}
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
ImageIO.write(binarized, "tiff", out); // You probably want to check return value (true/false)!
bufferedImages.add(image);
}
I am working with Java and combine two images. I save the combined image and want to delete the overlay, but it seems there are still streams open. And i don't know which and how to close them.
f_overlay and f_image are both Files.
// load source images
BufferedImage image = null;
BufferedImage overlay = null;
try {
log.debug(f_image.getAbsolutePath());
log.debug(f_overlay.getAbsolutePath());
image = ImageIO.read(f_image);
overlay = ImageIO.read(f_overlay);
} catch (IOException e) {
log.error(e.getMessage());
}
// create the new image, canvas size is the max. of both image sizes
int w = Math.max(image.getWidth(), overlay.getWidth());
int h = Math.max(image.getHeight(), overlay.getHeight());
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
// paint both images, preserving the alpha channels
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, 0, null);
// Save as new image
try {
ImageIO.write(combined, "PNG", f_image);
} catch (IOException e) {
log.error(e.getMessage());
}
// we can delete the overlay now
log.debug("Delete overlay: " + f_overlay.delete());
Are there any suggestions?
I can't see anything wrong in your code.
However, I would only delete the file f_overlay if the reading was successful. Important, after you call delete() on the file object, you must not use the object for anything else, so best is to assign f_overlay=null
boolean state = f_overlay.delete();
f_overlay=null;
log.debug("Delete ... "+state);
I'm developing an application using Java Opencv-2.4.4 and swing GUI. Problem is that I'm unable to find any solution, that shows efficient way how to print processed image (saved in Mat object) to java swing GUI. For this moment I'm using this clumsy solution:
javax.swing.JLabel outputImage;
outputImage.setIcon(new javax.swing.ImageIcon("/home/username/Output.png"));
private void sliderStateChanged(javax.swing.event.ChangeEvent evt) {
.
.
Mat canny; // Here is saved what I want to plot
String filename = "/home/username/Output.png";
Highgui.imwrite(filename, canny); // write to disk
outputImage.setIcon(new ImageIcon(ImageIO.read(new File(filename)))); //update Icon
.
.
}
When user changes some values, inputs etc ., in GUI I have to overwrite Output.png on disk and update jLabel with new image from disk.
Is there any more elegant / efficient solution to this ? Is it posible to plot or convert Mat object directly to Canvas or Image or anything that is printable as image in swing ?
Yes there is more elegant way to do it. You can concert Mat to BufferedImage type and then just Load it with swing. The code to convert it to Buffered image is:
Mat image_tmp = your image
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", image_tmp, matOfByte);
byte[] byteArray = matOfByte.toArray();
BufferedImage bufImage = null;
try {
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
} catch (Exception e) {
e.printStackTrace();
}
And then you just can paint it in your GUI object:
g.drawImage(bufImage , 0, 0, null);
where g is of type Graphics
Hope this helps.
jpeg encoding is interesting, but there are a couple problems:
it is not a lossless format, you will lose image data when compressing
it takes quite a while (around 6 to 10 times longer than the suggested one below)
public Image toBufferedImage(Mat m){
int type = BufferedImage.TYPE_BYTE_GRAY;
if ( m.channels() > 1 ) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels()*m.cols()*m.rows();
byte [] b = new byte[bufferSize];
m.get(0,0,b); // get all the pixels
BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return image;
}
This is a readymade solution for Imshow() equivalent in Java OpenCV Its simple to use. API will look like:
Imshow im = new Imshow("Title");
im.showImage(matimage);
Visit here https://github.com/master-atul/ImShow-Java-OpenCV
This is a better solution as you don't store the image into disk and read again. Hence it reduces the overhead of reading from a disk and thus is faster.
Using #andriy's anwser. I came up with this solution. I used JFrame instead of Graphics. Hope this helps.
public void imshow(Mat src){
BufferedImage bufImage = null;
try {
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", src, matOfByte);
byte[] byteArray = matOfByte.toArray();
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
JFrame frame = new JFrame("Image");
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(bufImage)));
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} catch (Exception e) {
e.printStackTrace();
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Convert pdf file to jpg asp.net
public class Pdf2Image {
private Image image;
int length;
public int convertPdf2Image(String pdfname) {
File file = new File(pdfname);
RandomAccessFile raf;
try {
raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new PDFFile(buf);
// draw the first page to an image
int num = pdffile.getNumPages();
length=num;
for (int i = 0; i <= num; i++) {
PDFPage page = pdffile.getPage(i);
//get the width and height for the doc at the default zoom
int width = (int) page.getBBox().getWidth();
int height = (int) page.getBBox().getHeight();
Rectangle rect = new Rectangle(0, 0, width, height);
int rotation = page.getRotation();
Rectangle rect1 = rect;
if (rotation == 90 || rotation == 270) {
rect1 = new Rectangle(0, 0, rect.height, rect.width);
}
//generate the image
BufferedImage img = (BufferedImage) page.getImage(
rect.width, rect.height, //width & height
rect1, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true // block until drawing is done
);
ImageIO.write(img, "png", new File("src\\downloadedFiles\\aa" + i + ".png"));
}
} catch (FileNotFoundException e1) {
System.err.println(e1.getLocalizedMessage());
} catch (IOException e) {
System.err.println(e.getLocalizedMessage());
}
return length;
}
public static void main(String[] args) {
Pdf2Image p = new Pdf2Image();
p.convertPdf2Image("src\\downloadedFiles\\todaypdf.pdf");
}
}
I am using this code to convert PDF file to image. It is working fine for most of the PDF's but showing exception for a PDF file. Exception is:
Expected 'xref' at start of table.
Could any one tell me why it is giving such an exception?
There are many malformed PDF files out in the wild and this is most likely one of them.
It is not possible to give a definite answer until seeing the problem PDF file. What I am guessing is that the 'startxref' specifies an absolute position into the PDF where the xref table should be located. The java library is jumping to this position on the file expecting to find the word 'xref' but cannot find it.
http://blog.amyuni.com/?p=1627
One way to fix this would be to load the file into the full version of Acrobat and then save the file. Acrobat will fix the xref offset as mentioned in the link.
There are quite large companies out there generating malformed PDF's that should know better. Adobe lets these files exist because it makes it hard for their PDF competitors to keep up and compete.