function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Kenji775Kenji775 

Use Visualforce as image server

Hey everyone,

I have a problem that probably has a lot of differnet answers so if you think you have a better approach feel free to let me know.

 

I am working on a visualforce page that has an HTML5 canvas element. The canvas loads an image from a publically available document. I need to get the base64 value of this image after the user has modified it. The problem is, because this is hosted on a force.com site, the domain is different than the the one that hosts the image. You cannot use canvas.toDataURL('image/jpeg') on a canvas that has content loaded via drawImage().

 

So the fix I see, like when you have to make a cross domain ajax request is to create a server side proxy. In this case, my proxy needs to act as an image server. I need the visualforce page to get the image requested (as a url argument) and display it, as if it was just an image, not a web page. Alternativly if i could get the base64 encoded value of the image and print that on the page, that would be fine as well.

 

Well feel free to leave any feedback as I am bit stuck for now. Thank you!

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

You can use SOA (the salesforce proxy server) to service your AJAX requests across (sub-)domains, although this will eat into your API request limits.

 

You could also make a visualforce page and have it render using the contentType attribute set to "image/jpeg" (or whatever type you need). You can't set the headers for the request (at least, not yet), so you won't be able to put out a Base64 image directly. However, it should be sufficient to simply write the un-blob'ed string data back to the client directly:

 

<apex:page showHeader="false" sidebar="false" standardStylesheets="false" controller="pageController" contentType="image/jpeg">
{!bodyContent}
</apex:page>

The controller itself should simply process the request's URL, grab the data requested, and return the result as a string inside of a function public String getBodyContent().

All Answers

sfdcfoxsfdcfox

You can use SOA (the salesforce proxy server) to service your AJAX requests across (sub-)domains, although this will eat into your API request limits.

 

You could also make a visualforce page and have it render using the contentType attribute set to "image/jpeg" (or whatever type you need). You can't set the headers for the request (at least, not yet), so you won't be able to put out a Base64 image directly. However, it should be sufficient to simply write the un-blob'ed string data back to the client directly:

 

<apex:page showHeader="false" sidebar="false" standardStylesheets="false" controller="pageController" contentType="image/jpeg">
{!bodyContent}
</apex:page>

The controller itself should simply process the request's URL, grab the data requested, and return the result as a string inside of a function public String getBodyContent().

This was selected as the best answer
Kenji775Kenji775

You sir are awesome. While I did find another work around for my issue (directly query the file data and base64 encode the blob, return to the caller) those are some awesome tips to know. I had no idea there was such a thing as the SOA I'm going to have to do more reading.

 

I figured I could do something like you mentioned in your second method, but I didn't quite know how to go about it. Thank you for that tip as well.

 

Just curious, how did you happen to know about those things? Not that it really matters, I just wonder where people pick up these seemingly obscure tricks sometimes ;)

Thanks again. 

sfdcfoxsfdcfox

All of this stuff is in the documentation. The hard part, of course, is knowing what to look for. The printed manual is literally thousands of pages, and even the developer resource files number a few hundred pages. Salesforce.com is such a feature-rich platform, that knowing all the ins and outs can take a while.

 

I personally know all this stuff from over six years of experience with the platform. I've almost always had the pleasure of working with pilot features, developer preview features, and so on. Also, since they mention new features with each release, I make sure I read the release notes, and figure out what method I'll need to take to get access to those features as early as possible. I was able to participate in the developer preview of Visualforce and Apex Code, for example.

 

Many features are released in Sandbox a month before they go live. I try to take advantage of these opportunities so that I can trend with the latest and greatest before it's publicly available. I try to attend the webinars, and I'm always refreshing my knowledge by finding clients that want to push the envelope, and when I'm not doing that, I do random projects in my own developer editions to keep myself in practice.

 

The only way I suppose a newer person could come in and gain all this knowledge would be to actually look at all the resources on this site (under the documentation section). Go through it one bit at a time, write up a practice item that uses this feature, and then continue on. Soon, you'll have hundreds of examples in your developer account that you can fall back on to help your organization or your clients.

 

Finally, use the community as a resource. We have all learned various aspects of the system, and many hints I would never have known about if I had not been active in the community forums.

CTCObrasCTCObras

Hi,
I'm using the same visualpage example that you are giving us, the code in the method is the next:

public string getBodyContent(){
		Blob bodyDocumentImage = [SELECT id,body FROM  Document WHERE Id =: '015V0000000DAWM'].body;
	    return bodyDocumentImage.toString();
	} 

The document is an image however I can't see the image. I hope you can helpe.

Thanks

Jamie TsaoJamie Tsao
Has anyone actually gotten the 2nd part of the selected answer to work?

I'm trying to do the exact same thing by having an VF page/controller serve/output a Blob from an Attachment object that is located on a different org.

<apex:page controller="pagecontroller" action="{!init}" 
    contentType="image/jpeg"  showHeader="false" sidebar="false" standardStylesheets="false">{!attachmentContent}</apex:page>
In the answer, it says:

"However, it should be sufficient to simply write the un-blob'ed string data back to the client directly"

"The controller itself should simply process the request's URL, grab the data requested, and return the result as a string inside of a function public String getBodyContent()."

When making the REST API call to the third-party org, the attachment body comes back in HttpResponse, but I tried getBody() (which returns String type) and it didn't work.

Anyone get this to work and how?
JWikkJWikk
this worked for us 
return EncodingUtil.base64Encode(doc.body);
Philip Meldrum08237737677563425Philip Meldrum08237737677563425
Following this lead I have this for my Apex class.
There is one document with a jpeg logo
public without sharing class aiETctl_Tracker {

    
    public aiETctl_Tracker(){
        
        
    }
    
    public string BodyContent;
    
    public string getBodyContent(){
       Document doc = [SELECT id,body FROM  Document Limit 1];
        
       return EncodingUtil.base64Encode(doc.body);
   } 
 }

This is the Visualforce Page:
<apex:page showHeader="false" sidebar="false" standardStylesheets="false" controller="aiETctl_Tracker" contentType="image/jpeg">
{!BodyContent}
</apex:page>

When I preview the page I get a small white box - no logo
What am I doing wrong please?