Publishing a post with a picture to the facebook page with restFb - java

When I publish a picture to my wall by
FacebookType publish = fc.publish("me/photos", FacebookType.class,
BinaryAttachment.with(attachmentName, temporaryStream),
Parameter.with("message", "my myssage"));
the post is created as expected. I can see a message and the published pictute under the message .
but when I want to do the same but on some pages wall instead the user wall by.
FacebookType publish = fc.publish(pageId + "/photos", FacebookType.class,
BinaryAttachment.with(attachmentName, temporaryStream),
Parameter.with("message", "my myssage"));
the post is published, but I can see only text. Not the picture. The picture can be seen only when I click on the date of the post. I can also reach this photo by clicking on the photos on the top of the page and then "name of the page" photos tab.
Is there any way how to see the photo as the part of the post also when I post it on a page?

I finally found a solution. To publish post with a photo to the section with normal "text only" posts you need publish a photo to your wall (your user wall not the wall of the page), then get its link and finally create a feed to the page with the the picture link.
here is the sample code:
FacebookType photo = fc.publish(pageid + "/photos" , FacebookType.class,
BinaryAttachment.with(photoName, photoInputStream));
Link photoLink = fc.fetchObject(photo.getId(), Link.class);
FacebookType post = fc.publish(pageid + "/feed", FacebookType.class,
Parameter.with("message", "your message"),Parameter.with("type", "photo"),
Parameter.with("link", photoLink.getLink()));
edit: I forgot about one thing. When you later delete the post, you do not delete to photo. To do that you have to do that manually.

Your Answer worked a treat and helped me untold amounts however i found with my solution I didn't need
FacebookType post = fc.publish(pageid + "/feed", FacebookType.class,
Parameter.with("message", "your message"),Parameter.with("type", "photo"),
Parameter.with("link", photoLink.getLink()));
as i would recive an error (that i should have copied to show you) but photoLink.getLink() returned null in my case.
so my updated solution ended up being
FacebookType photo = client.publish(groupId + "/photos",
FacebookType.class,
BinaryAttachment.with(imageName),
imageAsBytes,
"image/png"),
Parameter.with("message",
message));
Just my 2 cents, Thanks again for your help!
EDIT
Also while playing around I noticed that in the solution I arrived at I was creating a FacebookType photo object and this object doesn't get used anywhere, your just calling the publish method of the client that's created further up in your program.
my final class is below, (my application is taking an image from the computer and posing to a groups wall)
public void createImagePostInGroup(String message, String groupId, String imageFilePath){
byte[] imageAsBytes = fetchBytesFromImage(imageFilePath);
DefaultFacebookClient client =
new DefaultFacebookClient(accessToken, Version.LATEST);
client.publish(groupId + "/photos",
FacebookType.class,
BinaryAttachment.with(imageFilePath.substring(imageFilePath.length()-34),
imageAsBytes,
"image/png"),
Parameter.with("message",
message));
}
And my image is converted into a byte array in this method
private byte[] fetchBytesFromImage(String imageFile) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte fileContent[] = null;
try{
BufferedImage image = ImageIO.read(new File(imageFile));
ImageIO.write(image, "png", baos);
baos.flush();
fileContent = baos.toByteArray();
}catch (Exception e){
e.printStackTrace();
}
return fileContent;
}
Again thanks for your help.

Related

webview.evaluateJavascript apparently just not running for long strings

I have an android app I've programmed where most of the action happens in a html+javascript webView, and I have a couple of scenarios where I pass data and commands back and forth between the Java side and the WebView/JS side.
I've recently programmed a way for the JS side to trigger a registerForActivityResult(new ActivityResultContracts.GetContent(), ... call to allow the user to select an image, and it works, but when I try to send the data back from Java to my javascript, it fails.
public void onActivityResult(Uri uri) {
// this means I've got the URI selected from the gallery
try {
final InputStream imageStream = getContentResolver().openInputStream(uri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
selectedImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String ecImage = Base64.encodeToString(b, Base64.DEFAULT);
myWebView.evaluateJavascript("onImageSelectTest('" + ecImage + "')", null);
} catch (FileNotFoundException e) {
// e.printStackTrace();
}
}
After a bit of testing, I've found that it's only when the ecImage variable contains the base64 long string that the function doesn't run -- it runs just fine if I set ecImage = "abcd"; for example.
I want the webview to have the image for display purposes and, mainly, for posting the data to a web server, and right now for me the easiest way I can think of doing that is passing the image as a base64 string, but the evaluateJavascript call just isn't working with the long strings right now. I'm open to alternative ways of passing the image data to the webview.

How to allow the user to download a byte[] or base64 to their chosen directory

I want to allow the user to download a pdf file created in iText.
The expected result is that the user can download the pdf to their selected directory. The actual result is the file will not download.
I am generating a pdf using iText and passing the result back to my ajax call to allow the user to download the file. I have the base64. I checked that it was valid by using https://base64.guru/converter/decode/pdf This showed the pdf correctly. However, I can not get the result to download in the ajax ".done".
I have tried using:
byte[] decoder = Base64.getDecoder().decode(b64);
Before passing it back; however, I get an error message on ".getDecoder()" of "The method getDecoder() is undefined for the type Base64".
The java code is:
resourceImage = MySQLConnection.recipePDF(accountID, crID, servings, servingSize);
String imageDataString = Base64Encode2.encode(resourceImage);
System.out.println("imageDataString: " + imageDataString);
if (resourceImage == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No recipe pdf.");
} else {
String json = new Gson().toJson(imageDataString);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
The javascript/ajax code on the is:
.done(function(responseJson1a){
dataType: "json";
alert(JSON.stringify(responseJson1a));
download(responseJson1a, "resourcefile.pdf", "application/pdf");
});
A very simple answer. I needed to add "data:application/pdf;base64," to the start of the string.
download("data:application/pdf;base64,"+responseJson1a, "resourcefile.pdf", "application/pdf");

How to retrieve & share bitmap from device folder

I am building a meme generator app. So far, the app does everything I need it to do but I want to add 1 more functionality. The app saves the meme as a bitmap on my device. I want to add a functionality where, if the user wishes to share the meme on Facebook, Twitter, IG, etc, the app retrieves that same bitmap (which was just created.).
I'm not worried about the sharing function at the moment. I want to find out how I can retrieve the file to be able to share it.
This is the method where the creation and saving of the meme takes place. I will omit unnecessary code:
public void createBitmapAndSave(ImageView img) {
...
counter++;
File file;
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();
file = new File(path + "/SimpliMeme/" + timeStamp + "-" + counter + ".jpg");
file.getParentFile().mkdir();
try {
OutputStream stream = new FileOutputStream(file);
mutableBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
stream.flush();
stream.close();
Toast.makeText(getContext(), "Top Text: " + String.valueOf(topTextMeasurement) + " and bottom text: " + String.valueOf(bottomTextMeasurement),
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
Objects.requireNonNull(getContext()).sendBroadcast(mediaScanIntent);
}
and I've created an empty method that needs to be called when the user hits the "Share" button:
public void shareMeme(){}
Like you've mentioned earlier, you gotta divide this big method into 2 small ones.
As far as your initial question goes: There is no point in going back to your device just to find and get that same photo. Divide the method into 2 methods (createBitmap() & saveBitmap(), for example) and if the user just wants to share it without saving it to the device, the app will just call the createBitmap() method to only create the bitmap and then you'll use that in your upcoming sharing functionality.

unable save image in jsp

I'm unable to save a Data URI in JSP. I am trying like this, is there any mistake in the following code?
<%# page import="java.awt.image.*,java.io.*,javax.imageio.*,sun.misc.*" %>
function save_photo()
{
Webcam.snap(function(data_uri)
{
document.getElementById('results').innerHTML =
'<h2>Here is your image:</h2>' + '<img src="'+data_uri+'"/>';
var dat = data_uri;
<%
String st = "document.writeln(dat)";
BufferedImage image = null;
byte[] imageByte;
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(st);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
if (image != null)
ImageIO.write(image, "jpg", new File("d://1.jpg"));
out.println("value=" + st); // here it going to displaying base64 chars
System.out.println("value=" + st); //but here it is going to displaying document.writeln(dat)
%>
}
}
Finally, the image is not saved.
I think you didn't get the difference between JSP and JavaScript. While JSP is executed on the Server at the time your browser requires the web page, JavaScript is executed at the Client side, so in your browser, when you do an interaction that causes the JavaScript to run.
You Server (eg Apache Tomcat) will firstly execute your JSP code:
String st = "document.writeln(dat)";
BufferedImage image = null;
byte[] imageByte;
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(st);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
if (image != null)
ImageIO.write(image, "jpg", new File("d://1.jpg"));
out.println("value=" + st);
System.out.println("value=" + st);
As you can see, nowhere is the value of st changed. Your broser will receive the following snippet from your server:
value=document.writeln(dat);
Since your browser is the one that executes JavaScript, he will execute it and show the Base64-encoded Image - but your server won't.
For the exact difference, read this article.
To make the code working, the easiest way is to redirect the page:
function(data_uri)
{
// redirect
document.location.href = 'saveImage.jsp?img='+data_uri;
}
Now, you can have a JSP-page called saveImage.jsp that saves the Image, and returns the webpage you had already, and write the dara_uri into the element results.
Another, but more difficult way is to use AJAX. Here is an introduction to it.
You are trying to use JavaScript variables in Java code. Java code is running on your server, while Javascript code runs in user's browser. By the time JavaScript code executes, your Java code has already been executed. Whatever you're trying to do, you have to do it in pure javascript, or send an AJAX call to your server when your Javascript code has done it's thing.

stuck loading image to Oracle and retrieving in servlet

I thought this would be a quick fun project, but it's turning into a problem. :(
I want to load some images into an Oracle table and then later retrieve them with hibernate through a servlet.
So here's the portion of the loader that inserts the image.
String imageFileName = row[col++];
String ext = imageFileName.substring(imageFileName.lastIndexOf('.') + 1);
String imageFilePath = imageDir + imageFileName;
String mimeType = "image/" + ext;
image.setImageType(mimeType);
Image found = imageDAO.retrieve(imageId);
if(found==null){
//create a new one
byte[] bytes = loadImage(imageFilePath, mimeType);
image.setImageData(bytes);
image = imageDAO.create(image);
++created;
}
else{
//check if an update is needed
if(updateDate.after(found.getUpdated())){
byte[] bytes = loadImage(imageFilePath, mimeType);
found.setImageData(bytes);
found.setUpdated(updateDate);
image = imageDAO.update(found);
++updated;
}
}
}
and here's the servlet innards:
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
String imageId = request.getParameter(KeyNames.PARM_IMAGE_ID);
if(imageId==null){
throw new NullPointerException("Image ID parameter is required");
}
Image image = getImageDAO().retrieve(imageId);
if(image==null){
throw new IllegalArgumentException(imageId + " is not a valid image ID");
}
response.setContentType(image.getImageType());
response.getOutputStream().write(image.getImageData());
response.getOutputStream().close();
return null;
}
Seems simple to me, but when I hit the URL using my browser, I get:
"The image [url] cannot be displayed because it contains errors"
Since the servlet is wrapping successful, I must guess that either in the loading or in the retrieving, I've corrupted the image data. I'm out of guesses as to what to do next, so any advice is appreciated.
Shame on me! This is what I get for running code off the internet without actually studying it to find out what it does!
So the answer was that I was running the image through a writable raster in order to store in the DB. Well, DUH! when you rasterize the image, it's not a png anymore.
So I simply do a byte copy from the input file and store that in the blob and it works fine.
Shoot me now.
Thanks for the help!

Categories