threejs_playGnd
threejs_playGnd copied to clipboard
Cross-domain image for texture
Hi, first of all thank you so much for creating _three.js playGnd. I definitely started to play with three.js thanks to this.
Let me ask you about texture with a cross-domain image. I want to load images from Instagram and use it for textures for geometries. However, I haven't done yet.
On _three.js playGnd, I can see a texture by the following code.
map = THREE.ImageUtils.loadTexture('../texturez/proxy.php?url=http://distilleryimage6.ak.instagram.com/77a4df402ebf11e38c1322000a1fb036_7.jpg'); geometry = new THREE.CubeGeometry(200, 200, 200); material = new THREE.MeshLambertMaterial({shading: THREE.FlatShading, color: 0xdcdcdc, map: map}); mesh = new THREE.Mesh(geometry, material); map.wrapS = map.wrapT = THREE.RepeatWrapping; map.repeat.set( 1, 1 ); scene.add(mesh);
I use proxy.php you mentioned in Stack Overflow.
cross-domain image for three.js (canvas/webGL), proxy? - Stack Overflow http://stackoverflow.com/questions/17710414/cross-domain-image-for-three-js-canvas-webgl-proxy
In addition, I also set access control using express.js.
app.all("/", function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With"); res.header("Access-Control-Allow-Methods", "GET, PUT, POST"); return next(); });
I downloaded _three.js playGnd code from Github and had a look at, but I haven't found a solution. Did you do anything else on _three.js playGnd but use proxy.php?
Thanks in advance.
Forgot to mention:
- Three.js r58
- Googel Chrome 30.0.1599.69
- Mac OS 10.8.4
@nbriz mentions this in his short tutorial with Creator's Project
Basically you just need to prepend your link with ../texturez/proxy.php?url=
:
map = THREE.ImageUtils.loadTexture('../texturez/proxy.php?url=http://distilleryimage6.ak.instagram.com/77a4df402ebf11e38c1322000a1fb036_7')
if you build your objects in the editor this will also pre-fill it.
Thank you for comment. I meant that I can see a texture from a cross-domain image on playGnd editor, but I can' t outside the editor. Therefore, I want to ask how the editor can solve the cross domain policy problem when loading images.
Basically you just need to prepend your link with ../texturez/proxy.php?url=
:
map = THREE.ImageUtils.loadTexture('../texturez/proxy.php?url=http://distilleryimage6.ak.instagram.com/77a4df402ebf11e38c1322000a1fb036_7')
since proxy.php
is a script running on the server hosting the page… it doesnt run into cross-domain policy issues
@chimanaco it's always a hack to get images on other hosts as textures, it's technically against the rules ( for security reasons or whatever... don't totally understand why ). Like @yyolk mentioned the work-around is using a proxy like the one i posted on stackoverflow, here's the script i'm using:
<?php
// PHP Proxy
// Responds to both HTTP GET and POST requests
//
// Author: Abdul Qabiz
// March 31st, 2006
//
// Get the url of to be proxied
// Is it a POST or a GET?
$url = ($_POST['url']) ? $_POST['url'] : $_GET['url'];
$headers = ($_POST['headers']) ? $_POST['headers'] : $_GET['headers'];
$mimeType =($_POST['mimeType']) ? $_POST['mimeType'] : $_GET['mimeType'];
//Start the Curl session
$session = curl_init($url);
// If it's a POST, put the POST data in the body
if ($_POST['url']) {
$postvars = '';
while ($element = current($_POST)) {
$postvars .= key($_POST).'='.$element.'&';
next($_POST);
}
curl_setopt ($session, CURLOPT_POST, true);
curl_setopt ($session, CURLOPT_POSTFIELDS, $postvars);
}
// Don't return HTTP headers. Do return the contents of the call
curl_setopt($session, CURLOPT_HEADER, ($headers == "true") ? true : false);
curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// Make the call
$response = curl_exec($session);
if ($mimeType != "")
{
// The web service returns XML. Set the Content-Type appropriately
header("Content-Type: ".$mimeType);
}
echo $response;
curl_close($session);
?>
keep in mind, that ../texturez/proxy.php?= implies that u have a folder on ur server called "texturez" with a file called "proxy.php" ... so u need to make sure to save the code above as "proxy.php" onto ur own server, otherwise ur referencing a file that doesn't exist
Thank you guys for all help. Yes, I tried above things. I uploaded the following files on my server and tried them.
- proxy.php (same as one on playGnd. I put it in the same directory as index.html)
- index.html (copied from playGnd editor and modified a directory for proxy.php)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="http://brangerbriz.net/labs/threejs_playGnd/js/three.min.js"></script>
<script src="http://brangerbriz.net/labs/threejs_playGnd/js/Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var camera, scene, renderer;
var geometry, material, mesh;
function setup() {
var W = window.innerWidth, H = window.innerHeight;
renderer = new THREE.WebGLRenderer();
renderer.setSize( W, H );
document.body.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera( 50, W/H, 1, 10000 );
camera.position.z = 500;
scene = new THREE.Scene();
// paste your code from the geometryGUI here
map = THREE.ImageUtils.loadTexture('proxy.php?url=http://distilleryimage6.ak.instagram.com/77a4df402ebf11e38c1322000a1fb036_7.jpg');
geometry = new THREE.CubeGeometry(200, 200, 200);
material = new THREE.MeshBasicMaterial({shading: THREE.FlatShading, color: 0xdcdcdc, map: map});
mesh = new THREE.Mesh(geometry, material);
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.repeat.set( 1, 1 );
scene.add(mesh);
}
function draw() {
requestAnimationFrame( draw );
// experiment with code from the snippets menu here
renderer.render( scene, camera );
}
setup();
draw();
</script>
</body>
</html>
But I couldn't make it, that's why I asked if there is something I have to do except loading a image though proxy.php.
I guess my problem is on my server or somewhere or just a simple mistake. :(
Now I can get images on other hosts as textures. The way using proxy.php doesn't work for me (I still don't know why), but the way using corsproxy.com works. This is the second answer for one @nbriz posted on stackoverflow. Although I wish I could make it with proxy.php because I don't have to be dependent on someone's website, what I'm making is just a demo, so it's okay right now. I will try to use proxy.php again.
Then the code I'm using looks like the following.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.min.js"></script>
<script src="Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var camera, scene, renderer;
var geometry, material, mesh;
var canvas, context;
var imgW = 612;
var imgH = 612;
function setup() {
var W = window.innerWidth, H = window.innerHeight;
renderer = new THREE.WebGLRenderer();
renderer.setSize( W, H );
document.body.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera( 50, W/H, 1, 10000 );
camera.position.z = 1500;
scene = new THREE.Scene();
canvas = document.createElement("canvas");
canvas.width = imgW;
canvas.height = imgH;
context = canvas.getContext("2d");
var img = new Image();
img.crossOrigin = '';
var texture = new THREE.Texture(canvas);
img.onload = function() {
context.drawImage(img, 0, 0);
texture.needsUpdate = true;
scene.add(mesh);
};
img.src = 'http://www.corsproxy.com/distilleryimage6.ak.instagram.com/77a4df402ebf11e38c1322000a1fb036_7.jpg';
geometry = new THREE.CubeGeometry(imgW, imgH, imgW);
material = new THREE.MeshBasicMaterial({shading: THREE.FlatShading, color: 0xdcdcdc, map: texture});
mesh = new THREE.Mesh(geometry, material);
}
function draw() {
requestAnimationFrame( draw );
// experiment with code from the snippets menu here
renderer.render( scene, camera );
}
setup();
draw();
</script>
</body>
</html>
Thanks for taking time, @yyolk @nbriz !
thnx for sharing @chimanaco, nice to have options :)
@yyolk looks nice! Thank you for sharing!