About convert Image to byte[] and reverse in Java
Solution 1
Let's start with the paint code.
ImageIO.read(in)
is expecting a valid image format that one of it's pluggable service provides knows how to read and convert to a BufferedImage
.
When you pass the byes from extractBytes
, you're simply passing back an array of bytes that represents the actual image file. I'd be the same as saying Image.read(new File("image/pikachu.png"))
However, the data buffer returned from your extractBytes2
is returning a internal representation of the image data, which may not be "readable" by ImageIO
.
UPDATED
A BufferedImage is an accessible buffer of image data, essentially pixels, and their RGB colors. The BufferedImage provides a powerful way to manipulate the Image data. A BufferedImage object is made up of two parts a ColorModel object and a Raster object.
Referenced from here
UPDATED
I had this wacky idea on the way home of how to convert a BufferedImage
to a byte array...
The basic idea is to use ImageIO.write
to write out the BufferedImage
to a ByteOutputStream
...
public static byte[] extractBytes2(String ImageName) throws IOException {
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
ByteOutputStream bos = null;
try {
bos = new ByteOutputStream();
ImageIO.write(bufferedImage, "png", bos);
} finally {
try {
bos.close();
} catch (Exception e) {
}
}
return bos == null ? null : bos.getBytes();
}
Here's my test...
public class TestByteImage {
public static void main(String[] args) {
new TestByteImage();
}
public static byte[] extractBytes2(String ImageName) throws IOException {
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
ByteOutputStream bos = null;
try {
bos = new ByteOutputStream();
ImageIO.write(bufferedImage, "png", bos);
} finally {
try {
bos.close();
} catch (Exception e) {
}
}
return bos == null ? null : bos.getBytes();
}
public TestByteImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ImagePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ImagePane extends JPanel {
private BufferedImage original;
private byte[] byteData;
private BufferedImage fromBytes;
public ImagePane() {
String name = "/path/to/your/image";
try {
original = ImageIO.read(new File(name));
byteData = extractBytes2(name);
} catch (IOException ex) {
ex.printStackTrace();
}
setFont(UIManager.getFont("Label.font").deriveFont(Font.BOLD, 48f));
}
@Override
public Dimension getPreferredSize() {
return original == null ? super.getPreferredSize() : new Dimension(original.getWidth() * 2, original.getHeight());
}
protected void drawText(Graphics2D g2d, String text, int x, int width) {
BufferedImage img = new BufferedImage(width, getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D tmpg = img.createGraphics();
tmpg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
tmpg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
tmpg.setFont(g2d.getFont());
tmpg.setColor(Color.RED);
FontMetrics fm = tmpg.getFontMetrics();
int xPos = ((width - fm.stringWidth(text)) / 2);
int yPos = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
tmpg.drawString(text, xPos, yPos);
tmpg.dispose();
AffineTransform transform = g2d.getTransform();
g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(-10), x + (x + width) / 2, getHeight() / 2));
g2d.drawImage(img, x, 0, this);
g2d.setTransform(transform);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (original != null) {
g.drawImage(original, 0, 0, this);
drawText((Graphics2D) g, "Original", 0, original.getWidth());
}
if (byteData != null && fromBytes == null) {
try {
fromBytes = ImageIO.read(new ByteInputStream(byteData, byteData.length));
} catch (IOException exp) {
exp.printStackTrace();
}
}
if (fromBytes != null) {
g.drawImage(fromBytes, getWidth() - fromBytes.getWidth(), 0, this);
drawText((Graphics2D) g, "From Bytes", getWidth() - fromBytes.getWidth(), fromBytes.getWidth());
}
}
}
}
Solution 2
Use ImageIo to write bufferedImage into ByteArrayOutputStream, then invoke the toByteArray method of the stream.
dleviathan
"What you get by achieving your goals, is not as important as, what you become by achieving your goals." - Zig Ziglar
Updated on November 23, 2022Comments
-
dleviathan over 1 year
i have one problem when i convert image to byte[] and reverse:
I have 2 function convert image to byte[] as follow
public byte[] extractBytes2 (String ImageName) throws IOException { File imgPath = new File(ImageName); BufferedImage bufferedImage = ImageIO.read(imgPath); WritableRaster raster = bufferedImage .getRaster(); DataBufferByte data = (DataBufferByte) raster.getDataBuffer(); return ( data.getData() ); }
and
public byte[] extractBytes (String ImageName) throws IOException { Path path = Paths.get(ImageName); byte[] data = Files.readAllBytes(path); return data; }
I will have byte[] byteArray
byteArray = extractBytes2("image/pikachu.png");
or
byteArray = extractBytes("image/pikachu.png");
when i convert byte[] to Image i use
Graphics g = panelMain.getGraphics(); Graphics2D g2D = (Graphics2D) g; try { InputStream in = new ByteArrayInputStream(byteArray); BufferedImage image = ImageIO.read(in); g2D.drawImage(image, 0, 0, GiaoDienChinh.this); g2D.setPaint(Color.BLACK); panelMain.setOpaque(true); panelMain.paintComponents(g2D); } catch ( Exception e ) { } finally { }
but i only draw with byteArray use function "extractBytes" not with "extractBytes2" !!!
Anyone can explain me how i can draw image with byteArray which got from "extractByte2"?
Thanks for all support!
-
Andreas Dolk over 11 yearsI actually don't understand the problem: is method
extractBytes2
not working or not called or doesbyteArray
always holds the result ofextractBytes
when you paint the image?
-
-
dleviathan over 11 yearsthanks i see. But have any way i can use byteArray from
extractBytes2
to draw image?