Pannellum 2.1

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.

This entry was posted in and tagged , , . Bookmark the permalink.

71 Responses to Pannellum 2.1

  1. Gumir J says:

    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

    • Matthew Petroff says:

      Tiles are generated using generate.py. Run python3 generate.py for usage instructions. In addition to Python, the Python Pillow package needs to be installed, and nona is needed from Hugin.

      • Gumir J says:

        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

        • Matthew Petroff says:

          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 containing generate.py and then run the command. It will print content to the terminal, but no other windows will open.

  2. Gumir J says:

    That’s what I’m trying to do
    ScreenShot
    http://gumirj.com/files/phyton.jpg

  3. Matthew Petroff says:

    You’re passing the argument for nona without a value. Try python path/to/generate.py -n path/to/nona.exe path/to/image.jpg.

  4. Gumir J says:

    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

    • Matthew Petroff says:

      There’s only a static picture preview if you have the preview attribute set to an image, so remove it. Then add autoLoad: true to have the panorama automatically load on page load.

  5. Gumir J says:

    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.

  6. Gumir J says:

    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…

  7. Mart says:

    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?

    • Matthew Petroff says:

      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.

      • Mart says:

        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.

        • Matthew Petroff says:

          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.

  8. Gumir J says:

    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…

  9. Francisco says:

    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

    • Matthew Petroff says:

      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.

  10. csaenz says:

    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.

    • Matthew Petroff says:

      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

  11. Oz Ramos says:

    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” :)

  12. Emon says:

    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’

  13. Hello Matthew, how can I install Pannellum to run in my Drupal 7 website? Is there any documentation on this?

    • Matthew Petroff says:

      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.

  14. 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

    • Matthew Petroff says:

      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.

  15. Linwood says:

    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.?

    • Matthew Petroff says:

      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).

  16. LaurentD says:

    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’

    • Matthew Petroff says:

      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.

      • LaurentD says:

        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

        • LaurentD says:

          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

  17. LaurentD says:

    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

    • Matthew Petroff says:

      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.

  18. Geetika says:

    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

    • Matthew Petroff says:

      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.

  19. Florian Rist says:

    Hey Matthew,
    Is it possible to run it locally (LOCALHOST/OFFLINE) on PC ?
    Thanks in Advance :)

  20. Derek says:

    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

    • Matthew Petroff says:

      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 get nona‘s usage information printed if you just paste C:\Program Files (x86)\Hugin\bin\nona.exe in a command prompt and press enter?

      • Derek says:

        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

        • Matthew Petroff says:

          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 use generate.py without the -n flag.

          • Derek says:

            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.

  21. Micky Surisiay says:

    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

  22. Derek says:

    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.

    • Matthew Petroff says:

      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.

      • Derek says:

        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.

        • Matthew Petroff says:

          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:

          <link rel="stylesheet" href="https://cdn.pannellum.org/2.3/pannellum.css"/>
          <script type="text/javascript" src="https://cdn.pannellum.org/2.3/pannellum.js"></script>
          
          <div id="panorama"></div>
          
          <script>
          // Create viewer
          viewer = pannellum.viewer('panorama', {your JSON configuration});
          
          // Get current yaw
          var yaw = viewer.getYaw();
          
          // Set yaw
          viewer.setYaw(30);
          </script>
          

          Take a look at the API reference page for documentation of the API.

          • Derek says:

            Wonderful, many thanks Matthew and happy new year.

          • Derek says:

            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

          • Matthew Petroff says:

            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 a resize 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 via viewer.on('load', your_listener_function);, where viewer is the Pannellum instance. There wasn’t a method to actually check if a panorama is currently loaded, so I just added a isLoaded API method to check this.

  23. Derek says:

    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.

    • Matthew Petroff says:

      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.

      • Derek says:

        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.

        • Matthew Petroff says:

          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 replace alert("message") with function() { alert("message"); }.

  24. Martin says:

    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

    • Matthew Petroff says:

      The generate.py script uses the nona stitching utility from Hugin. You’re trying to have the script use nano instead, which is a text editor, so of course it fails.

  25. nicholi says:

    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?

    • Matthew Petroff says:

      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, and vOffest parameters to manually set the panorama’s horizontal angle of view, vertical angle of view, and vertical offset angle, respectively.

  26. Ashish says:

    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.

    • Matthew Petroff says:

      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 the loadScene 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.

  27. Urfeena Hamid says:

    Hello Matthew, I want to use Pannellum in my Angular 4 project. Is it possible? If possible, how to use its API?

  28. Diego Lopes says:

    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

    • Matthew Petroff says:

      This can be done with the API: img = viewer.render(viewer.getPitch(), viewer.getYaw(), viewer.getHfov(), {returnImage: true});, where viewer is the Pannellum instance, should return a data URI of the current view.