I'm creating a speed dial extension for myself (I know there's a lot of speed dial extension, but most of them will display ads, and my antivirus threat them as PuP), I wanted to save website's logo image, let user either place one picture by themselves, or give the url of the picture.
I am stuck with how to save images in chrome's offline storage (https://developer.chrome.com/apps/offline_storage#table), there's no example for saving other file types.
How do I save picture on google chrome's offline storage?
Take a look at chrome.storage API:
5MB data limit or unlimited if the extension has the unlimitedStorage permission
content scripts can directly access user data without the need for a background page.
It's asynchronous and therefore faster than the blocking and serial localStorage API.
User data can be stored as objects (the localStorage API stores data in strings). Only simple JSON-serializable objects are supported, though.
localStorage serializes everything so you'll have to convert the image to a dataurl first:
var xhr = new XMLHttpRequest();
xhr.open('GET', favicon_url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(r) {
if (xhr.status != 200) {
return;
}
localStorage.icon = 'data:image/png;base64,' +
btoa(String.fromCharCode.apply(null, new Uint8Array(xhr.response)));
}
xhr.send();
This is a simplified example which assumes png image type.
chrome.fileSystem API might be a better choice. (not suitable for an extension as it's only for apps)
HTML5 FileSystem API: currently could be the best choice but the API is no longer maintained by W3C so it's unclear whether it stays in the future.
I would convert the image to a data URL. At that point it's just a string so it's easy to save. For examples of data URL images see: https://en.wikipedia.org/wiki/Data_URI_scheme#Examples
I usually convert images to data URLs on the command line with cat whatever.png | base64 but there are a number of websites that will do it for you, if you prefer.
Hope that helps.
To create images yourself (Remember to change the mime type to whatever you need):
cat /apple/Downloads/80.png | printf "%s%s%s" '<img src="data:image/png;base64,' "$(base64 -w0)" '" alt="Red dot" />'
Examples of sites that will create data URLs for you:
http://www.base64-image.de/step-1.php
http://dataurl.net/#dataurlmaker
I've made a fiddle to show how to use the file API to get an image as a data URL: https://jsfiddle.net/quvvtkwr/
Related
I'm experimenting with Chrome browser extensions. I want to be able to take any text input into the browser (through the URL bar of the browser or onto text boxes on social media sites and so on) and send that text to a server. I'm wondering if this is possible in chrome and what functions I need to use to achieve this?
I suspect the logic of the extension would work something like this: any time a link is clicked where there is text in an input form / text box, extract that text or form input and send it using some JS requests library to a server.
Which Chrome API function can be used to get the text input into a form?
You can get DOM information (input, textareas, etc) using content_script which has direct access to the web page data. URL data can be accessed through either the popup.js or background.js using the chrome API chrome.tab.query.
In the past I have had the best luck using MutationObservers, this looks at real-time changes to the web page (or wherever you specify you want the observer to be). Then you can send that data to the server.
small example.
function extractinputdata() {
var inputdata = document.getElementById('some specfic HTML element')
if (inputdata != null) {
new MutationObserver(function(){
//when a change has been made to the element or its children, you can record the new data
}).observe(inputdata, {characterData: true, childList: false, subtree:true});
}
}
I need to make a website with an private image inside of <img /> tag, which mean you cannot view it any where outside that website. I need the image to not be displayed even if the user try to copy the src of the image and open it in another tab of the same browser.
Is it possible? If so, how can i achieve that?
Short answer: no. Long answer: not possible :-)
If you can get at it in any way (and you must be able to do that to get it to render in a browser), you can save it locally.
All someone would have to do is access it with a munged copy of a browser that saves all incoming data to disk.
There are ways to obfuscate the image so that the user won't be able to just copy and paste the URL, you can use the Javascript Image object to create a new image and drawImage to draw it into a canvas, however you'll still need to obtain the image data somehow, perhaps making an ajax request for the actual image on the server. However a really persistent user can inspect your javascript code and do some reverse engineering to get the image source.
A more naive user will just take an screenshot of the image and achieve the same effect.
So any attempt to try to prevent the user from copying the image is futile.
I’ve to display a image in a picture box in VisualWebGui. I’ve image in string format.
string ImageString_P;
FileStream fs_P = new FileStream(LocalDirectory + "Page_2.tif", FileMode.Open, FileAccess.Read);
byte[] picbyte_P = new byte[fs_P.Length];
fs_P.Read(picbyte_P, 0, Convert.ToInt32(fs_P.Length));
ImageString_P = Convert.ToBase64String(picbyte_P);
Now, how can I display this image(ImageString_P) in the picture box. Should I create the image of this string data or can I directly display this data in the PictureBox?
If I’ll create the image in a path(suppose “c:\xyz.jpg”) . How it (xyz.jpg) will be displayed in the picturebox.
Visual WebGui is a web application and as such it basically needs to let the browser specifically request any graphics data that should be rendered, which is fundamentally different from that of desktop applications, where you can simply assign the graphics data itself to the image property of a PictureBox.
If you study how a webpage with a PictureBox is rendered to the browser in Visual WebGui, you will see that the PictureBox is rendered as an img tag with the source being set to an Url, which is responsible for serving the image to the browser. When the browser sees that Url on the img tag, it issues another request to the server for the contents of that Url. This "secondary" request is called a gateway request in Visual WebGui.
To serve the graphics to the browser, you need some kind of Gateway in your Visual WebGui application. There are a few types of predefined gateways in Visual WebGui, like for Images (ImageResourceHandle) and icons (IconResourceHandle), but in this case you have a dynamically generated image, so you will need to define your own gateway to serve the graphics contents.... or you can write the image data to, say, Resources\Images folder of your application and then use an ImageResourceHandle to reference it.
Defining your own gateways in Visual WebGui is very simple, and you can see quite a few examples here.
Hope this helps,
Palli
You can do like this:
string ImageString_P;
FileStream fs_P = new FileStream(LocalDirectory + "Page_2.tif", FileMode.Open, FileAccess.Read);
byte[] picbyte_P = new byte[fs_P.Length];
this.picMyPicture.Image = new DynamicStreamResourceHandle(contentBitmap, "image/jpeg");
and it should render fine.
My packaged app gets images from google drive and then display them on the side. But I can't get the images to be displayed. I am trying to get the url of the image so that I can put that url in an image source. The image url that I am getting is actually an html page rather than jpeg, png etc. I have looked at the reference guide for google picker but nothing seems to work.
I am using this
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
fileName = data.docs[0].name;
imgURL = data.docs[0].url;
}
I want to use imgURL as the source for image selection but imgURL is not something like "https//:www.example.com/image.jpg. It is rather an html page I want something that ends with file type only then it will be able to display the image. Please let me know how can I get the image to be displayed in html page of my packaged app after selecting it from google drive.
You should fetch the metadata of the image, then use the webContentLink of the image, then the user can view it in a logged in browser. See the documentation on downloads for more information.
I have many large KML data-sets, which are served using a hierarchy of region-based network-links; as described in the KML reference:
Using Regions in conjunction with NetworkLinks, you can create a hierarchy of pointers, each of which points to a specific sub-Region. The <viewRefreshMode>, as shown in the following KML file, has an onRegion option, which specifies to load the Region data only when the Region is active. If you provide nested Regions with multiple levels of detail, larger amounts of data are loaded only when the user's viewpoint triggers the next load.
This works nicely when loaded in Google Earth.
I now wish to load these in an application using the Google Earth plug-in. And I need to access the loaded content via the Google Earth API; (i.e. attach click events, alter styles) to integrate the content into the application.
The issue is, I haven't found any reference to an 'on-load' event for network links. In my mind, the way this would work is:
Load top-level network link via the API, attaching a call-back function which will be invoked when the network-link is loaded.
In the call-back function, parse the KML returned by network link. For intermediate levels in the regionation hierarchy, this KML will contain only network links to the next regionation level. Load these into the plug-in via the API, again specifying the same call-back function, which will be invoked when these are loaded (i.e. when their region becomes visible).
Eventually, the KML returned will contain the actual 'content'. At this stage we load the actual content (i.e. placemarks) into the plug-in, after performing any desired modifications (e.g. attaching event-listeners, setting styles, etc).
I'm thinking the javascript would look something like the following.
Please note: this is just a rough sketch to perhaps aid in understanding my question. I am NOT asking why this code doesn't work.
//create network link
var networkLink = ge.createNetworkLink("");
networkLink.setName("Regionated hierarchy root");
// create a Link object
//the network-links contained in the kml that will be returned in this file
//are region-based; they will only be loaded when the user zooms into the relevant
//region.
var link = ge.createLink("");
link.setHref("http://foo.com/regionatedRoot.kml");
// attach the Link to the NetworkLink
networkLink.setLink(link);
//specify the callback function to be invoked when the network link is loaded
//this is is the part that doesn't actually exist; pure fiction...
networkLink.onLoad = networkLinkLoaded;
// add the NetworkLink feature to Earth
ge.getFeatures().appendChild(networkLink);
// function which will be invoked when a network-link is loaded
// i.e. when its region becomes active
function networkLinkLoaded(kml) {
//parse the kml returned for child network links,
//this will create the network link KmlObject, with a
//region specified on it.
for (childNetworkLink in parseNetworkLinks(kml)) {
//and append them, again hooking up the call-back
childNetworkLink.onLoad = networkLinkLoaded;
ge.getFeatures().appendChild(childNetworkLink);
}
//if the user has zoomed in far enough, then the kml returned will
//contain the actual content (i.e. placemarks).
//parse the kml returned for content (in this case placemarks)
for (placemark in parsePlacemarks(kml)) {
//here we would attach event-listeners to the placemark
ge.getFeatures().appendChild(placemark);
}
}
Is this possible?
Have I taken a wrong turn in my thinking? I believe I have followed recommended practices for managing large KML datasets, but I am unsure how to use these via the API.
Addendum:
As an example of the type of problem I am trying to solve:
Imagine you are building a web application using the Google Earth Plugin, and you want to display a placemark for every set of traffic-lights in the world. The placemarks should only display at an appropriate level-of-detail (e.g. when the camera is at 5km altitude). When a user clicks on a placemark, we want the web app to load statistics for that set of traffic-lights, and display them in a sidebar.
How would you engineer this?
You wouldn't need access to the object data directly to provide the functionality you require. You would handle the data load exactly like you have done, using a hierarchy of region-based network-links.
Then if your usage scenario is like the one you set out in your addendum then you would simply use the target data from the click event to load your statistical data based on the placemarks as required.
For example, you could simply set up a generic mousedown event handler on the window object and then test to see if the target is a placemark. You can add this generic listener before you load any data and it will still be fired when you click on your dynamically loaded placemarks. There is no need to attach individual event-listeners to the placemarks at all.
e.g.
window.google.earth.addEventListener(ge.getWindow(), 'mousedown', onWindowMouseDown);
var onWindowMouseDown = function(event) {
if (event.getTarget().getType() == 'KmlPlacemark') {
// get the placemark that was clicked
var placemark = event.getTarget();
// do something with it, or one of its relative objects...
var document = placemark.getOwnerDocument();
var parent = placemark.getParentNode();
// etc...
}
}
Not sure if this is quite what you want but there is a kmltree api that will:
build out the kml tree for you based on the kml given
allow you to have a 'kmlloaded' event handler
http://code.google.com/p/kmltree/
function initCB(instance){
ge = instance;
ge.getWindow().setVisibility(true);
var gex = gex = new GEarthExtensions(ge);
var tree = kmltree({
url: 'http://foo.com/regionatedRoot.kml',
gex: gex,
mapElement: $('#map3d'),
element: $('#tree'),
});
$(tree).bind('kmlLoaded', function(event, kmlObject){ //do something here });
tree.load();
}
it does require you to bring in another js api but it works pretty good and gives you some good built in functionality.
So far I haven't found anything just from the plug-in that will fire an event when the kml is loaded...
you might be able to try using fetchKml() especially if you are hardcoding that url for the link in there?
google.earth.fetchKml(ge, 'http://foo.com/regionatedRoot.kml', function(kmlObject){
//do logic here
});