openseadragon / openseadragon

An open-source, web-based viewer for zoomable images, implemented in pure JavaScript.
http://openseadragon.github.io/
BSD 3-Clause "New" or "Revised" License
3.01k stars 594 forks source link

Get Column and Row name (Finding the Image) #694

Closed Sityle closed 9 years ago

Sityle commented 9 years ago

Hello,

how can i get the column and row name of mouse position or click position ? I need that to find the image which is shown at the cursor position.

iangilman commented 9 years ago

You'll have to loop through the images in the world and compare the mouse position with their bounds. Here is an example:

http://codepen.io/iangilman/pen/PqxvgN

Sityle commented 9 years ago

Thanks for your answer but that doesnt solve my problem. Let me explain a little bit more.

I have one viewer Object:

var viewer = OpenSeadragon ({ id: 'container', prefixUrl: './src/openseadragon/images/', tileSources: './neno/GeneratedImages/dzc_output.xml', minZoomLevel: 1, maxZoomLevel: 50, debugMode: true
});

This object represents every image in my view. In your example you are adding 20 elements of tilesource. I dont want to do that because my viewer already contains every image.

Here is what i exactly want to get. In Debug mode i see the "ROW" and the "COLUMN". If i concat this both as follow "COLUMN_ROW".png it represents the image name. So this is why i want to get this both attributes without iterating over known count of tilesources and adding them to an object as in your example.

iangilman commented 9 years ago

So you have a single image that has embedded in it a number of areas you want to think about as separate objects? You would do something similar to my example, but rather than looking at the bounds of tiled images, you'd run some math on the coordinate space.

It looks like you're not specifying a viewport width for your image, so it'll use the default width of 1. Let's say your image has 10 areas across...if the mouse X (in viewport coordinates) is between 0 and 0.1, it'll be in the first area, if it's between 0.1 and 0.2 it'll be in the second, etc. Same idea for the vertical dimension, keeping in mind that the entire image height is based on its aspect ratio.

Does that make sense?

Sityle commented 9 years ago

So it still do not solve my problem. Let me explain a little bit more. I have a big image with high resolution that i splitted with Deep zoom composer of microsoft. The resolution are many .png files and a xml file. With openseadragon i can show this via this code:

var viewer = OpenSeadragon ({ id: 'container', prefixUrl: './src/openseadragon/images/', tileSources: './neno/GeneratedImages/dzc_output.xml', minZoomLevel: 1, maxZoomLevel: 50, debugMode: true });

So what i have now is many small .png files where i can zoom in. See image: bsp In this image you will see that openseadragon shows me the column and the row number of every image he is rendering. The column and the row name are the image names of this part. This is why i want to get this both attributes.

So if i have the possibility to get the Shown columns and rows i can iterate them and find this one where my mouse is on.

iangilman commented 9 years ago

Interesting...I'm curious, why do you want this? Keep in mind that it changes as you zoom in and out.

At any rate, that information is stored in the lastDrawn array of OpenSeadragon.Tile objects in a TiledImage. This isn't part of the official API, but you can still use it (at least for now). Here is an example:

var $viewerElement = $('#seadragon-viewer')
    .on('mousemove', function(event) {
        var pixel = new OpenSeadragon.Point(event.clientX, event.clientY);
        var viewerPosition = $viewerElement.position();
        pixel.x -= viewerPosition.left;
        pixel.y -= viewerPosition.top;
        var image = viewer.world.getItemAt(0);
        var tile;
        for (var i = 0; i < image.lastDrawn.length; i++) {
            tile = image.lastDrawn[i];
            if (pixel.x > tile.position.x && 
                    pixel.y > tile.position.y && 
                    pixel.x < tile.position.x + tile.size.x &&
                    pixel.y < tile.position.y + tile.size.y) {
                console.log('column: ' + tile.x + ', row: ' + tile.y);
                return;
            }            
        }
    });

Note that the tiles are positioned in web coordinates (unlike the previous examples I gave you which used viewport coordinates).

Sityle commented 9 years ago

Thank you very much this is exactly what i want to get. So i can imagine that you are curious but i promiss if the project ends i will inform you and you will see that it make sence :-D. I would be happy if this part will be a part of the next api.

iangilman commented 9 years ago

I look forward to seeing the result! :)