【问题标题】:openseadragon get selection dataurl/blobopenseadragon 获取选择数据url/blob
【发布时间】:2017-08-14 13:28:04
【问题描述】:

我从 openSeadragonSelection 检索一个矩形:

观众:

this.viewer = OpenSeadragon(this.config);
this.selection = this.viewer.selection({
    showConfirmDenyButtons:  true,
    styleConfirmDenyButtons: true,
    returnPixelCoordinates:  true,
    onSelection:  rect => console.log(rect)
});
this.selection.enable();

通过 onSelection 调整:

t.SelectionRect {x: 3502, y: 2265, width: 1122, height: 887, rotation:0, degrees: 0, …}

我不知道如何通过 rect 从我的查看器实例中获取画布。

this.viewer.open(new OpenSeadragon.ImageTileSource(this.getTile(this.src)));

一个自行实现的 imageViewer 返回了所选区域的画布。所以我可以获取 blob 并将其发布到服务器:

    onSave(canvas){
        let source = canvas.toDataURL();
        this.setState({source:source, crop: false, angle: 0});
        save(this.dataURItoBlob(source), source.match(new RegExp("\/(.*);"))1]);
    }

    dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(dataURI.split(',')[1]);
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Blob([ia], {type:mimeString});
    }

如何通过 rect 获取查看器的图像。也应考虑轮换。

@iangilman

非常感谢您的建议。我创建了另一个我裁剪的画布,然后将其放回查看器中。我不确定你的库是否支持类似的东西:

const viewportRect = self.viewer.viewport.imageToViewportRectangle(rect);
const webRect = self.viewer.viewport.viewportToViewerElementRectangle(viewportRect);
const { x, y, width, height } = webRect || {};
const { canvas } = self.viewer.drawer;
let source = canvas.toDataURL();

const img = new Image();
img.onload = function () {
  let croppedCanvas = document.createElement('canvas');
  let ctx = croppedCanvas.getContext('2d');
  croppedCanvas.width = width;
  croppedCanvas.height = height;
  ctx.drawImage(img, x, y, width, height, 0, 0, width, height);
  let croppedSrc = croppedCanvas.toDataURL();
  //update viewer with cropped image
  self.tile = self.getTile(croppedSrc);
  self.ImageTileSource = new OpenSeadragon.ImageTileSource(self.tile);
  self.viewer.open(self.ImageTileSource);
}
img.src = source;

尚未考虑轮换。

【问题讨论】:

    标签: image image-processing canvas openseadragon


    【解决方案1】:

    我想您需要将矩形转换为正确的坐标,然后创建第二个画布并将 OSD 画布中的适当位复制到第二个画布中。

    看起来选择矩形可能在图像坐标中? OSD 画布将在 web 坐标中,或者在 HDPI 显示器上可能是两倍。 OSD 有很多转换功能,例如:

    var viewportRect = viewer.viewport.imageToViewportRectangle(imageRect);
    var webRect = viewer.viewport.viewportToViewerElementRectangle(viewportRect);
    

    您可以通过OpenSeadragon.pixelDensityRatio了解像素密度。

    一旦你有了合适的矩形,应该很容易从一个画布复制到另一个画布。我不确定您如何合并旋转,但它可能就像向其中一个画布上下文添加旋转调用一样简单。

    对不起,这有点含糊,但我希望它有所帮助!

    【讨论】:

    • 我用预实现更新了我的帖子,这就是你的意思吗?
    • 是的,看起来不错。我没有考虑将新裁剪的图像放回查看器中……这样做的目的是什么?无论如何,看起来你做得很好。一件事:ctx.drawImage 会接受一个画布,所以你不需要经历创建图像的过程。
    • 我将其放回原处,以便能够继续修改裁剪后的图像。我将仔细研究pixelDenityRatio。非常感谢?
    • 明白了。您还可以考虑使用 TiledImage.setClip 作为在查看器中裁剪图像的一种方式。无论如何,任何工作! :)
    • 即使你使用type: 'image',它仍然在使用 TiledImage 对象,所以 setClip 仍然可以工作。
    猜你喜欢
    • 2013-02-25
    • 1970-01-01
    • 2020-03-20
    • 2018-06-15
    • 1970-01-01
    • 2016-06-10
    • 2011-05-15
    • 2021-03-27
    • 2020-02-01
    相关资源
    最近更新 更多