Over the past five months, I have continued working on Pannellum and just released version 2.1.0. This release includes a number of improvements including a loading bar for equirectangular panoramas, “inertia,” configuration from Photo Sphere XMP data, more descriptive error messages, and more documentation. The loading bar is something I’ve wanted since the beginning but never had a good way of implementing before, since Image
objects don’t have progress events. To add support for using Photo Sphere XMP data, I needed access to raw data that wasn’t available with Image
objects. Researching that, I learned that XMLHttpRequest Level 2 supports blob objects that allow the raw image to be transfered; before, it was possible but was a bad idea as it involved some ugly character code hacks. This extended functionality is a few years old at this point, but since the name didn’t change, plenty of information sources are out of date. Configuration from Photo Sphere XMP data seems to work, but without an Android device capable of making them, I was not able to test a number of corner cases. The improved error messages should hopefully resolve one of the most commonly reported issues, why a large panorama doesn’t work, since it now explicitly says that the image is too big and lists what the device’s largest supported image size is. Also of note, I changed the naming of a few configuration parameters for consistency; this breaks some existing configurations, but it will be better going forward. Lastly, numerous bugs were also fixed.
Recent Posts
Archives
Categories
Hi
I installed Python 3.4 … I can not figure out how to start generating tiles. There is such generate.py and examplepano.jpg, that should be written in *.bat file?
Thnx
Tiles are generated using
generate.py
. Runpython3 generate.py
for usage instructions. In addition to Python, the Python Pillow package needs to be installed, andnona
is needed from Hugin.Thank you. But for me, the photographer, it is difficult to understand. Yes, I installed the library Pillow-2.7.0.win-amd64-py3.4.exe and Hugin. Also launched via the command line way … \ python.exe generate.py … but nothing happens box appears for a moment .. no action. I think need detailed “step-by-step” instructions. IMO
It should be better documented. However, I’ve also never used it on Windows. I’m not sure what you mean by “box appears for a moment.” You need to open a command prompt and
cd
to the directory containinggenerate.py
and then run the command. It will print content to the terminal, but no other windows will open.That’s what I’m trying to do
ScreenShot
http://gumirj.com/files/phyton.jpg
That’s the run dialog, not the command prompt. Run
cmd.exe
there to open a command prompt.Sorry, it’s nothing :( Display an error, about which I know nothing :)
http://gumirj.com/files/cmd.jpg
Windows 8.1 Intel Core i5 (x64)
Python-3.4.2.amd64.msi (x64)
Pillow-2.7.0.win-amd64-py3.4.exe (x64)
HuginSetup_2014.0.0_64bit_Windows.exe (x64)
Regards, Gumir
You’re passing the argument for
nona
without a value. Trypython path/to/generate.py -n path/to/nona.exe path/to/image.jpg
.Thank you, Matthew! It seems it works :) Wonderful lightweight player!!! And last question: how to disable a static picture preview and click event and loading bar… because for multiresolution this is not necessary.
Regards, Gumir
There’s only a static picture preview if you have the
preview
attribute set to an image, so remove it. Then addautoLoad: true
to have the panorama automatically load on page load.I shared my work and information about Pannellum 2.1.1. on social networks: Facebook, Twitter, Google+, VK. I think in the near future will be a lot of downloads from your project page :)
Great Work! Thanks.
http://gumirj.com/pannellum/index.html?config=single.json
I think, need to work on improving rendering for large screen frame (like full browser screen). Ie when a large area of the screen, panorama braking on slower computers. In the rest in development has a great future…
I’m using Pannellum on my site, but I can’t figure out what the best image type and size is for this tool. Large images are too big for some devices, and high quality types such as png are too heavy.
Any tips?
If you’re using an equirectangular image, I’d go with a 4096px wide JPEG, as this is supported by 99% of WebGL-capable devices. For higher resolution images, I would recommend making a multiresolution panorama using the
util/multires/generate.py
utility, but that is much more involved.Oke thanks, unfortunately, the 4096px wide JPEG doesn’t work on all phones.
For instance: my iphone 5s will show an odd black/white lines image. It will work only up to a size of 3237px wide.
I’ve done little testing on mobile devices, since I don’t own a smartphone. However, someone just donated an iPhone 5c for development / testing, so I should be able to start working on issues such as the one you described.
It seems to me – 1) the use of equi or 6 cube faces – you can forget it because there is no encryption of the project file and all images can be stolen; 2) Using multiresolution – it is the right way and only way in the direction – of optimization for mobile and file protection theft…
Greetings friend,
Is there any functionality in Pannellum to rescue the horizontal and vertical value of the event click somewhere on the Pano image?
thank you very much
Not at the moment. Currently, Pannellum doesn’t integrate well other scripts on a page as it uses an isolated
iframe
, without an API. I’m in the process of refactoring it so it can be used as a JavaScript library. After that’s done, I’ll start adding an events API, which could include click events.Ok thanks, I’ll be waiting for news about this… ;)
Hello again:
Is there a way to achieve this result with panellum modifying the parameters? I’ve done hundreds of tests and the best result I’ve had is this.
Thanks in advance for your time and help.
C.S.
You need to use the
vaov
parameter to set the panorama’s vertical angle of view (which looks to be about 62 degrees). Try this:pannellum.htm?panorama=examplepano.jpg&title=London%20Calling%20Bar&author=Webmaster&autoLoad=true&vaov=62
Thanks Matthew, this rocks!!! It’s a great way to showcase the inside of your workplace on something like a contact page instead of just a Google Maps. It adds that extra little “something” :)
When I try to run following command it says
C:\pannellum-2.1.1\utils\multires>python generate.py
Traceback (most recent call last):
File “generate.py”, line 29, in
from PIL import Image
ImportError: No module named ‘PIL’
You need to have the Pillow Python package installed, as mentioned in the README.
Hello Matthew, how can I install Pannellum to run in my Drupal 7 website? Is there any documentation on this?
As mentioned in the README, you need to upload
pannellum.htm
to your server. It’s static content, so it doesn’t matter that you’re running Drupal or any other CMS.Hello Matthew,
Thanks for providing the Pannellum player!
When I try to show somewhat bigger equis I get an error message
“This panorama is too big for your device! It’s 12000px wide, but your device only supports images up to 8192px wide. (…)”
My “device”(?) is a Windows 7 x64 system and I’m using Firefox 42.0.
Is it true that it can’t display equirectangulars bigger than 8192 px wide?
Thanks in advance,
Wolfgang
Yes, your computer can’t display larger equirectangular images. It’s a limitation of your graphics card / driver. To display larger panoramas, they would need to be converted to cubic format, or ideally multires format.
I just wanted to say thank you not only for doing this, but for continuing to fix bugs. I got hit by a couple in the released version, and looked and sure enough they are fixed in the development branch; fetch and merge and fixed. Then another on high density mobile displays – and sure enough you already fixed.
I am curious if you might comment on what future plans you have, for example the (I think) undocumented image links, should they be used, are they going away, are they stable, etc.?
At the moment, I’m working on getting a new release out, with much better documentation. After that, I want to implement support for HDR panoramas and work on the new API. As for image hot spots, they’re not going away (although I’m not particularly happy with their implementation).
Dear Matthew,
I’m having an issue with the generate.py script.
It creates the 6 faces properly but is blocked when creating the tiles.
Looks like a windows related issue – it cannot find the tif files whereas they are created.
I tried different -o options, without success. The tiff files are created and are accessible.
Any idea?
thanks
D:\EBC\Panotest\utils\multires>generate.py -o d:\EBC\out\ -n “C:\Program Files\Hugin\bin\nona.exe” DSCF2583_stitch2.jpg
Processing input image information…
C:\Users\I054796\AppData\Local\Programs\Python\Python35\lib\site-packages\PIL\Image.py:2215: DecompressionBombWarning: I
mage size (179437568 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
DecompressionBombWarning)
Generating cube faces…
Generating tiles…
Traceback (most recent call last):
File “D:\EBC\Panotest\utils\multires\generate.py”, line 101, in
face = Image.open(os.path.join(args.output, faces[f]))
File “C:\Users\I054796\AppData\Local\Programs\Python\Python35\lib\site-packages\PIL\Image.py”, line 2286, in open
% (filename if filename else fp))
OSError: cannot identify image file ‘d:\\EBC\\out\\face0000.tif’
My best guess is that there’s something wrong with your Pillow installation such that it can’t load TIFF images. The library is reading the image from disk but can’t figure out what it is.
Hi Matthew,
I reinstalled previous python & pillow versions (from 3.5.1 to 3.4.3) but the are no differences. Still the same error message.
I then tried to open it directly from python’s console using the image.open statement, and it fails with the same error message for the cube face image files, but it works with a tif file I created with image editor. (took one of the sample jpg and converted into tif).
>>> Image.open(“D:\EBC\Panotest\examples\examplepano.tif”)
It looks like there is an issue with the tiff file created in the first step of the process. I can however open them with a image editing software. Would there be an issue with the size of the facexxxx.tif file? they are about 100MB each.
Thanks
laurent
Pillow can open the tif face file (without changes like size,…) if I save it into png and then back to tif again. So it looks like nona is creating tif files which can’t be read by pillow, at least in my case…
Hugin version: 2015.0.0
Pillow version: 3.0.0
Python version: 3.4.3
OS: Win Server 2012
Hello Matthew –
A friend could use the script (still have the hope to understand how to have it run on my side…)
I’m however facing another issue. The pano loads without error messages but remains black on both chrome & ie11.
The images in the folders are not black; they look correct. Any direction on where to look at?
Thanks
Laurent
First make sure there are no messages in the browser’s JavaScript console. Use the network tab of the browser’s developer tools to make sure it is loading the images you think it is. It could be some sort of driver issue if it is only one computer that has issue with display.
Sir,
Thanks for this wonderful tool, but having problem regarding full screen mode & icons on it. Sir, I want to make the html page default open to FULLSCREEN mode without having to manually press the RECTANGULAR BUTTON, & if it is possible to put some icons – since I want to make it custom MENU within full screen.
Thanks
It is impossible to make it automatically open in fullscreen. Allowing web pages to do this would be a huge security flaw, so browsers don’t allow it.
Hey Matthew,
Is it possible to run it locally (LOCALHOST/OFFLINE) on PC ?
Thanks in Advance :)
Yes. You just need to run a local web server.
Hi Matthew
I’ve been using Pannellum with a standard equirectangular images and creating a couple of tours. Thank you.
I’m now trying to move on to multires images. I have installed Python, Pillow, and Hugin, and tried a command line..
py generate.py 300.jpg -n “C:\Program Files (x86)\Hugin\bin\nona.exe”
The command prompt window reports..
Processing input image information…
Generating cube faces…
Traceback (most recent call last):
File “generate.py”, line 102, in
subprocess.check_call({args,nona, ‘-0’, os.path.join(args.output, ‘face’), os.path.join(args.output, ‘cubic.pto)])
File “C:Python\lib\subprocess.py”, line 579, in check_call
retcode = call(*popenargs, **kwargs”)
File “C:Python\lib\subprocess.py”, line 560, in call
with Popen(popenargs, **kwargs) as p:
File “C:Python\lib\subprocess.py”, line 950, in __init__
restore_signals, start_new_session)
File “C:Python\lib\subprocess.py”, line 1220, in _execute_child
startupinfo)
FileNotFoundError: {WinError 2} The system cannot find the file specified
An output folder in the Python directory is created, and it is populated by a single file “cubic.pto”, but that is all.
Any ideas as to where I might be going wrong?
The image I’m asking to be converted is a equirectangular image, is that okay?
I’m using Windows 8.1, Python 3.5, Hugin version 2016.0.0.3b4e2790cb90, and Pillow 3.2.0.
Best wishes and many thanks in advance.
Derek
You’re correct to be using an equirectangular image—it’s the only kind supported as input. The error suggests that Python can’t find the
nona
executable. However, you appear to be specifying it correctly, so I’m not really sure why it isn’t finding it. Do you getnona
‘s usage information printed if you just pasteC:\Program Files (x86)\Hugin\bin\nona.exe
in a command prompt and press enter?Hi Matthew
Many thanks for the prompt response. You’re a star.
Yes, executing Nona.exe from the command prompt brings up the usage information.
Kind regards
Derek
I’m at a bit of a loss then; I don’t see any obvious reason why it wouldn’t work. The only thing I can think of is to add
C:\Program Files (x86)\Hugin\bin
path and try to usegenerate.py
without the-n
flag.I tried without the -n flag, but no luck.
After many uninstalls, reboots, and reinstalls, I gave up and tried on another PC. It worked first time on this. Then when my back was turned, it did an automatic upgrade to Windows 10, and guess what, that PC is now giving the same error.
Maybe this is a python version related error.
Hey Matthew,
I was wondering if it’s possible to write custom functions, based on hotspots.
I.e. I have a panorama of a library with a hotspot on a particular book. What I want is for a user to click on that book and get a point and/or make a textbox appear and/or communicate with the backend of my project.
Thanks in advance for answering!
MickyS
I just added the ability to add a click handler to a hot spot, which should assist with what you’re trying to do (you’ll need to use the development version from Git to use it until the next release). Last month, I added the ability tospecify custom hot spot tooltips, which also might be useful.
Hi Matthew,
Love the new device orientation mode and custom hotspots in version 2.3. I have a question about the custom hotspots but could find nowhere else to ask the question but here on the 2.1 page.
I have custom hotspots working with the API, but not in the JSON. Am I correct to deduce that custom hotspots are not supported in the JSON config files?
Kind regards and best wishes for 2017.
The JSON configuration file only specifies the CSS class name for custom hotspots to use. As the CSS class needs to be defined elsewhere, the API has to be used as you correctly deduced.
Thanks for the quick response Matthew.
Sorry, more questions.
1) Is there a way to define the CSS class and associated javascript elsewhere and still use the custom hotspots in the JSON?
2) With version 2.1 I was using DOM references to read and set values in pannellum. Eg.
panoElement = parent.document.getElementById(‘Pano’);
panoContent = panoElement.contentWindow;
PanoIsLoaded = panoContent.loaded;
ActualPanAngle = panoContent.config.yaw;
This approach appears to no longer work with version 2.3.
The examples give only show how to use the API to create a new pannellum panorama. Can you give me an example of how to use the API with javascript to read and set pannellum values in response to a user action.
1) Take a look at the custom hot spots example. You need to first define the CSS in the HTML page and then create the viewer using the API, with the CSS class names specified in the JSON configuration.
2) Here’s an example for getting and setting the viewer’s yaw:
Take a look at the API reference page for documentation of the API.
Wonderful, many thanks Matthew and happy new year.
Hi Matthew
I have this working now, but there appears to be a hotspot positioning error when the panorama div is resized.
If the browser is resized at the same time, no problem, but if the div is resized with JavaScript (in my case to make room for a google map) then the hotspot stay in the same screen position whilst the panorama moves to the left.
This does not occur when using iframes and an external JSON file.
Can you also give me an example of how the isLoading function should be used with the example code above? There are certain actions that I want to happen only when the panoramic image is loaded. I used to use the JavaScript
Pano=parent.document.getElementById(‘Pano’);
PanoContent=Pano.contentWindow;
PanoIsLoaded=PanoContent.loaded;
This approach no longer works.
Many thank, I want you to know that your time is much appreciated and not taken for granted.
Regards
Derek
JavaScript’s resize listener can only be attached to the window, not individual elements. Thus, when just the
<div>
is resized, the viewer doesn’t know anything changed. I just added aresize
method to the API, so the viewer can be notified that it was resized.There’s a
load
event you can add a listener to viaviewer.on('load', your_listener_function);
, whereviewer
is the Pannellum instance. There wasn’t a method to actually check if a panorama is currently loaded, so I just added aisLoaded
API method to check this.Thanks for adding the “resize” and “isLoaded” method. When may I be able to download an updated version of Pannellum that will include these features?
The current load event appears to occur as soon as Pannellum is loaded, rather than the panoramic image.
It will probably be a while before the next release. You can always use the current version from Git, though.
The
load
event fires when the image finishes loading for me, like it’s supposed to. Based on the code structure, I’m not really sure how it would fire sooner.I’m obviously not using the event listener correctly. I’ve tried many combinations of
LeftPanoHi.on(“load”, alert(“Has loaded”));
document.getElementById(‘LeftPanoHi’).on(“load”, alert(“Has loaded”));
LeftPanoHi.addEventListener(“load”, alert(“Has loaded”));
where “LeftPanoHi” is the Pannellum instance, and the alert function always fires.
Can you point me in the right direction.
The way your code is structured, it’s evaluating the
alert
statement and trying to attach the event listener to the result; hence, the alert is displayed immediately. You need to replacealert("message")
withfunction() { alert("message"); }
.That sorts it; thank you for the lesson.
Hi, I want to execute “generate.py” for generate VR photo.
I got error as below, anything I missing?
admin$ python generate.py -n /usr/local/Cellar/nano/2.7.4/bin/nano -o output/ 22665222766_07524ca21a_k.jpg
Processing input image information…
Generating cube faces…
Invalid operating directory
Traceback (most recent call last):
File “generate.py”, line 106, in
subprocess.check_call([args.nona, ‘-o’, os.path.join(args.output, ‘face’), os.path.join(args.output, ‘cubic.pto’)])
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py”, line 540, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command ‘[‘/usr/local/Cellar/nano/2.7.4/bin/nano’, ‘-o’, ‘output/face’, ‘output/cubic.pto’]’ returned non-zero exit status 1
The
generate.py
script uses thenona
stitching utility from Hugin. You’re trying to have the script usenano
instead, which is a text editor, so of course it fails.Any recommendation on how to manually resize an Android panoramic photo? My image is 14336×1964 (basically a full 360 panorama shot). Pannellum displays and works great on desktop browser, but obviously can’t be viewed on mobile devices.
I tried a simple resize with GIMP, but then the new image came out completely messed up when viewed in Pannellum. I also can’t use the generate.py script because the aspect ratio is not 2:1. So…what does one do?
You need to make sure the Photo Sphere XMP metadata is preserved (there’s an option in GIMP’s JPEG export dialog for writing XMP). The other way is to use Pannellum’s
haov
,vaov
, andvOffest
parameters to manually set the panorama’s horizontal angle of view, vertical angle of view, and vertical offset angle, respectively.Hi Matthew,
You did a fantastic work with this plugin!
I am implementing this plugin in one of the website, is there a way I can show panorama images in a slider. As images are not interconnected hence I am using one image for one area.
Now I want to have this implemented in a slider, so that you can user slide through the images and view the panorama view too.
Take a look at the custom controls example and the
loadScene
API method. Add all the images to one configuration, like creating a tour, but don’t link them with hot spots. Then add custom controls for cycling through the images, which call theloadScene
method with the appropriate scene ID to cycle through the images. However, if you’re trying to mix panoramas with regular images, it will be more difficult, since you’ll have to figure out how to integrate Pannellum with whatever slider library you’re trying to use.Hello Matthew, I want to use Pannellum in my Angular 4 project. Is it possible? If possible, how to use its API?
I don’t see any reason why it wouldn’t work with Angular 4. The API is documented at pannellum.org.
Good morning Matthew.
I would like to know if it’s possible to get a snapshot of the positioned part of the picture with Pannellum framework? How can I do this?
Thank you in advance
This can be done with the API:
img = viewer.render(viewer.getPitch(), viewer.getYaw(), viewer.getHfov(), {returnImage: true});
, whereviewer
is the Pannellum instance, should return a data URI of the current view.