I want to implement a Java program where a client will be able to upload a file(image, text etc) from the client side and it being sent to the server side where the file will be stored in a folder on the server computer.
Is this possible and realistic? Is EJB a better way of doing this? Are there any good resources available?
You can create a class in a common package as follows, then call createByteArray() from client-side and convert image into a byte array. Then pass it into a skeleton and reconstruct an image using createBufferedImage(). Finally, save it as a JPEG using toFile():
/**
*
* #author Randula
*/
public class TransportableImage {
/**
*
* #param bufferedImage
* #return
* #throws IOException
*/
public byte[] createByteArray(BufferedImage bufferedImage)
throws IOException {
byte[] imageBytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JPEGImageEncoder jpg = JPEGCodec.createJPEGEncoder(bos);
jpg.encode(bufferedImage);
bos.flush();
imageBytes = bos.toByteArray();
bos.close();
return imageBytes;
}
//Reconstruct the BufferedImage
public BufferedImage createBufferedImage(byte[] imageBytes)
throws IOException {
InputStream is = new ByteArrayInputStream(imageBytes);
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(is);
BufferedImage image = decoder.decodeAsBufferedImage();
is.close();
return image;
}
//Save a JPEG image
public void toFile(File file, byte[] imageBytes)
throws IOException {
FileOutputStream os = new FileOutputStream(file);
os.write(imageBytes, 0, imageBytes.length);
os.flush();
os.close();
}
}
Related
I have a server and I want to compress images in it. When I write the image, it goes from 23MB to 650kb and it's okay. But when I'm reading it to send it to my client app, the size is back to 23MB.
public static BufferedImage getProfilePicture(String username) throws IOException {
File input = new File(profilePicturePath + File.separatorChar + username + ".png");
BufferedImage image = ImageIO.read(input);
rewriteImage(image);
return image;
}
public static String getProfilePictureBase64(String username) throws IOException {
BufferedImage img = getProfilePicture(username);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, "png", os);
return Base64.getEncoder().encodeToString(os.toByteArray());
}
So my question is : How can I keep the compressed size to send image to my client ?
Anybody have any idea about,How to handle unstructured data like Audio,Video and Images using Hbase.I tried for this alot but i didn't get any idea.please any help is appreciated.
Option 1: convert image to byte array and you can prepare put request and insert to table. Similarly audio and video files also can be achieved.
See https://docs.oracle.com/javase/7/docs/api/javax/imageio/package-summary.html
import javax.imageio.ImageIO;
/* * Convert an image to a byte array
*/
private byte[] convertImageToByteArray (String ImageName)throws IOException {
byte[] imageInByte;
BufferedImage originalImage = ImageIO.read(new File(ImageName));
// convert BufferedImage to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "jpg", baos);
imageInByte = baos.toByteArray();
baos.close();
return imageInByte;
}
Option 2 : You can do that in below way using Apache commons lang API. probably this is best option than above which will be applicable to all objects including image/audio/video etc.. This can be used NOT ONLY for hbase you can save it in hdfs as well
See my answer for more details.
For ex : byte[] mediaInBytes = org.apache.commons.lang.SerializationUtils.serialize(Serializable obj)
for deserializing, you can do this static Object deserialize(byte[] objectData)
see the doc in above link..
Example usage of the SerializationUtils
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.commons.lang.SerializationUtils;
public class SerializationUtilsTest {
public static void main(String[] args) {
try {
// File to serialize object to it can be your image or any media file
String fileName = "testSerialization.ser";
// New file output stream for the file
FileOutputStream fos = new FileOutputStream(fileName);
// Serialize String
SerializationUtils.serialize("SERIALIZE THIS", fos);
fos.close();
// Open FileInputStream to the file
FileInputStream fis = new FileInputStream(fileName);
// Deserialize and cast into String
String ser = (String) SerializationUtils.deserialize(fis);
System.out.println(ser);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Note :jar of apache commons lang always available in hadoop cluster.(not external dependency)
I have trouble to sending data from Android Client to NodeJS Server.
I use Socket.IO-client java library in my client.
But, there is not much information for me.
How can i sending binary data from android client to nodejs server?
You can use Base64 to encode the image:
public void sendImage(String path)
{
JSONObject sendData = new JSONObject();
try{
sendData.put("image", encodeImage(path));
socket.emit("message",sendData);
}catch(JSONException e){
}
}
private String encodeImage(String path)
{
File imagefile = new File(path);
FileInputStream fis = null;
try{
fis = new FileInputStream(imagefile);
}catch(FileNotFoundException e){
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
//Base64.de
return encImage;
}
So basically you are sending a string to node.js
If you want to receive the image just decode in Base64:
private Bitmap decodeImage(String data)
{
byte[] b = Base64.decode(data,Base64.DEFAULT);
Bitmap bmp = BitmapFactory.decodeByteArray(b,0,b.length);
return bmp;
}
I want to receive an uploaded image as a byte array (so that it can be inserted into a sql database).
I also want to show the uploaded image as a preview.
I have tried the following code but im not receiving the bytes of the full image. (if i print the byte array it prints only a few characters)
final Embedded preview = new Embedded("Uploaded Image");
preview.setVisible(false);
final Upload upload = new Upload();
upload.setCaption("Image");
// Create upload stream
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Stream to write to
upload.setReceiver(new Upload.Receiver() {
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
return baos; // Return the output stream to write to
}
});
upload.addSucceededListener(new Upload.SucceededListener() {
#Override
public void uploadSucceeded(Upload.SucceededEvent succeededEvent) {
final byte[] bytes = baos.toByteArray();
preview.setVisible(true);
preview.setSource(new StreamResource(new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
return new ByteArrayInputStream(bytes);
}
}, ""));
}
});
image.setSource(new StreamResource(new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
return new ByteArrayInputStream(baos.toByteArray());
}
}, ""));
You could try adding a ProgressListener with some logs to the Upload to see what is happening; you will get the amount of read bytes and total content length as a parameter to the updateProgress method so you can see if everything is being sent.
After receiving the uploaded file i want to return a byte[ ] representing the uploaded file i overrode the receiveUpload methode:
/**
* Invoked when a new upload arrives.
*
* #param filename
* the desired filename of the upload, usually as specified
* by the client.
* #param mimeType
* the MIME type of the uploaded file.
* #return Stream to which the uploaded file should be written.
*/
public OutputStream receiveUpload(String filename, String mimeType);
But it returns an OutputStream
Here's the full implementation :
class FileUploaderReceiver implements Receiver{
public File file;
#Override
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
OutputStream fos = null; // Stream to write to
try {
// Open the file for writing.
file = new File("/tmp/uploads/" + filename);
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
new Notification("Could not open file<br/>",
e.getMessage(),
Notification.Type.ERROR_MESSAGE)
.show(Page.getCurrent());
return null;
}
return fos; // Return the output stream to write to
}
So how to get the byte[ ], i know that i can retrieve it using the ByteArrayOutputStream class, but i'am blocked.
Any idea will be appreciated,
Thank you
Wrap the OutputStream with a ByteArrayOutputStream, then use toByteArray().
As kostyan mentioned, you need to use an InputStream (with respect to your method intention). From the InputStream, you can get the bytes, using something like this: http://lasanthals.blogspot.de/2012/09/get-byte-array-from-inputstream.html.
Do note, I provide this as a quick answer, from a quick search, have not tried this one myself.
The problem is how to be notified when the data is fully written to the returned stream.
You can return a ByteArrayOutputStream with overriden close() method. When the stream gets closed, you'll know that the upload was fully written to that stream.
public OutputStream receiveUpload(String filename, String mimeType) {
return new ByteArrayOutputStream() {
#Override
public void close() throws IOException {
byte[] uploadData = toByteArray();
//....
}
};
}