How to save BufferedImage to FastDFS in Java? - java

I have an image and I do somethings with it, finally I get an BufferedImage object(the sub image of original image), now I want to save the sub image to FastDFS without save it in my local, what should I do?
I have already save sub image as file to my local, but I don't want to do like this, because it makes waste.
String oriPicPathInFastDFS = "http://127.0.0.1/xx/xx/xx/xx";
BufferedImage image = null;
try {
image = ImageIO.read(new URL(oriPicPathInFastDFS));
} catch (IOException e) {
e.printStackTrace();
}
// do something
// this is the sub image that I want to save to FastDFS
BufferedImage subImage = image.getSubimage(5, 5, 5, 5);
// these code can save the sub image to my local and then upload to fastDFS
String localPath = "/home/xx/x/xx.jpg";
File detectionFile = new File(localPath);
try {
detectionFile.createNewFile();
ImageIO.write(subImage, "jpg", detectionFile);
} catch (IOException e) {
e.printStackTrace();
}
// upload to fast dfs
I want to upload the subImage to fastDFS without save it to my local.

Fine, I got a method to solve this question.
// change the BufferedImage to byte[]
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
boolean flag = ImageIO.write(sunImage, "jpg", out);
} catch (IOException e) {
e.printStackTrace();
}
byte[] byteArray = out.toByteArray();
// then save the byteArray to fast DFS

Related

Java sending image through network with ImageIO

I have a network program that sends a stream of BufferedImages through a network using ImageIO.write(..), this is working as intended apart from sometimes the Image received on the other end will just be a series of small black and white squares for a long time, then it will eventually switch back to sending the actual images.
I can't find any help with this anywhere.
I'm using Java version 1.8.0_65, I send the image like so:
BufferedImage capture = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
BufferedImage newImage = new BufferedImage(capture.getWidth(), capture.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
newImage.createGraphics().drawImage(capture, 0, 0, newImage.getWidth(), newImage.getHeight(), null);
capture = newImage;
BufferedImage difference = null;
if (lastImage != null) {
difference = getDifferenceImage(capture, lastImage);
} else {
difference = capture;
}
long generated = System.currentTimeMillis() - start;
ImageIO.write(difference, "png", socket.getOutputStream());
socket.getOutputStream().flush();
Try this code:
public byte[] getCustomImageInBytes(BufferedImage originalImage) {
byte[] imageInByte = null;
try {
// convert BufferedImage to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "png", baos);
baos.flush();
imageInByte = baos.toByteArray();
baos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageInByte;
}
socket.getOutputStream().write(getCustomImageInBytes(difference));
socket.getOutputStream().flush();

How to upload bufferedImage without storing it in user's system?

I am a beginner in java, and I am trying to write a simple screen-capture program. I wrote a simple SWING desktop app with a button and a text-field, and what I am trying to do is, when a user clicks that button the app takes a snapshot of the screen using awt.Robot, and sends that image and the text to a PHP script on my server.
My snapshot function so far is:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = new File("screenshot_full.png");
ImageIO.write(bufferedImage, "png", file);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
As you can see it's fairly simple so far, however I am not sure how to send that image to my PHP script without actually storing the image on user's PC.
Oh and I am using apache httpClient library for communicating to the web server. For the text I guess I can pass it in the URL as a get query, but I am not sure what to do about the image.
ImageIO.write can to an OutputStream of your choice.
So if you don't want to write the image to a File, you can simply write it to a different stream instead...
For example...
OutputStream os = null;
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
os = ...;
ImageIO.write(bufferedImage, "png", os);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
os.close();
} catch (Exception exp) {
}
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
Of course, I have no idea where you're sending the data, so you'll need to define the OutputStream yourself.
If you have the memory for it, you could write it a ByteArrayOutputStream and then write this to whatever output stream you need in the future...
To slightly modify your existing method, perhaps you could use a temporarily file and then delete it when you are finished with it. Perhaps it might look something like:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = File.createTempFile(Long.toString(System.currentTimeMillis()), ".png");
ImageIO.write(bufferedImage, "png", file);
//send image
file.delete();
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
Another alternative would be to construct an int[][] from your BufferedImage which will hold the RGB values for every pixel of the image:
public int[][] getColors(final BufferedImage image){
assert image != null;
final int[][] colors = new int[image.getWidth()][image.getHeight()];
for(int x = 0; x < colors.length; x++)
for(int y = 0; y < colors[x].length; y++)
colors[x][x] = image.getRGB(x, y);
return colors;
}
I am a little unsure about what you hope to achieve; What do you plan on doing with the image?
Why don't you make this a WebsService and let your PHP consume it? You could send the binary data through the WebsService using some sort of Base64 encoder.
You could do this to get the bytes of the BufferedImage:
byte[] binaryData = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();

creating .bmp image file from Bitmap class

I've created an application that uses sockets in which the client receives the image and stores the data of the image in Bitmap class....
Can anyone please tell me how to create a file named myimage.png or myimage.bmp from this Bitmap object
String base64Code = dataInputStream.readUTF();
byte[] decodedString = null;
decodedString = Base64.decode(base64Code);
Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0,decodedString.length);
Try following code to save image as PNG format
try {
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
}
out.flush();
out.close();
Here, 100 is quality to save in Compression. You can pass anything between 0 to 100. Lower the digit, poor quality with decreased size.
Note
You need to take permission in Android Manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Edit
To save your image to .BMP format, Android Bitmap Util will help you. It has very simple implementation.
String sdcardBmpPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/sample_text.bmp";
Bitmap testBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_text);
AndroidBmpUtil bmpUtil = new AndroidBmpUtil();
boolean isSaveResult = bmpUtil.save(testBitmap, sdcardBmpPath);
try {
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}

writing to pbm file using java ImageIo

I am trying to convert pages of a pdf to .pbm images. I am using following code for conversion:
for (int i=0; i<pages.size(); i++) {
PDPage singlePage = (PDPage) pages.get(i);
int pageno=i+1;
BufferedImage buffImage = null;
String imagefilename=prefix+"-"+pageno+".pbm";
try {
buffImage = singlePage.convertToImage();
} catch (IOException e1) {
System.out.println("Font not found");
return;
}
try {
File output=new File(imagefilename);
if (buffImage!=null){
ImageIO.write( buffImage, "pbm", output);
}
} catch (Exception e) {
System.out.println("File can not be written, check permission?");
}
}
When I am trying to write to png files, this seem to work perfectly, but I can not write to pbm files. ImageIO.write( buffImage, "pbm", output); returns false. What can be a possible remedy?

In Java is it possible to convert a BufferedImage to an IMG Data URI?

I have created a graphical image with the following sample code.
BufferedImage bi = new BufferedImage(50,50,BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = bi.createGraphics();
// Draw graphics.
g2d.dispose();
// BufferedImage now has my image I want.
At this point I have BufferedImage which I want to convert into an IMG Data URI. Is this possible? For example..
<IMG SRC="data:image/png;base64,[BufferedImage data here]"/>
Not tested, but something like this ought to do it:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bi, "PNG", out);
byte[] bytes = out.toByteArray();
String base64bytes = Base64.encode(bytes);
String src = "data:image/png;base64," + base64bytes;
There are lots of different base64 codec implementations for Java. I've had good results with MigBase64.
You could use this solution which doesn't use any external libraries. Short and clean! It uses a Java 6 library (DatatypeConverter). Worked for me!
ByteArrayOutputStream output = new ByteArrayOutputStream();
ImageIO.write(image, "png", output);
DatatypeConverter.printBase64Binary(output.toByteArray());
I use Webdriver, get captcha, like this below:
// formatName -> png
// pathname -> C:/Users/n/Desktop/tmp/test.png
public static String getScreenshot(WebDriver driver, String formatName, String pathname) {
try {
WebElement element = driver.findElement(By.xpath("//*[#id=\"imageCodeDisplayId\"]"));
File screenshot = element.getScreenshotAs(OutputType.FILE);
// base64 data
String base64Str = ImageUtil.getScreenshot(screenshot.toString());
return base64Str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getScreenshot(String imgFile) {
InputStream in;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
String base64Str = new String(Base64.getEncoder().encode(data));
if (StringUtils.isAnyBlank(base64Str)) {
return null;
}
if (!base64Str.startsWith("data:image/")) {
base64Str = "data:image/jpeg;base64," + base64Str;
}
return base64Str;
}

Categories