mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
fix: better handling png image size for scale < 2 (#6688)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
parent
0763624688
commit
21a5f07870
@ -27,6 +27,7 @@
|
||||
|
||||
import { getFileUrl } from '../file'
|
||||
import { getPreviewType, previewTypes } from '../filetypes'
|
||||
import { imageSizeToRatio } from '../image'
|
||||
import { BlobMetadata, FilePreviewExtension } from '../types'
|
||||
|
||||
export let file: Ref<Blob>
|
||||
@ -68,8 +69,8 @@
|
||||
return
|
||||
}
|
||||
const pR: number = mD?.pixelRatio ?? 1
|
||||
const fWidth: number = mD.originalWidth / pR
|
||||
const fHeight: number = mD.originalHeight / pR
|
||||
const fWidth: number = imageSizeToRatio(mD.originalWidth, pR)
|
||||
const fHeight: number = imageSizeToRatio(mD.originalHeight, pR)
|
||||
let mHeight: number = 0
|
||||
let scale: number = 1
|
||||
if (fWidth > pWidth) {
|
||||
|
@ -15,6 +15,11 @@
|
||||
|
||||
import extract from 'png-chunks-extract'
|
||||
|
||||
export function imageSizeToRatio (width: number, pixelRatio: number): number {
|
||||
// consider pixel ratio < 2 as non retina and display them in original size
|
||||
return pixelRatio < 2 ? width : Math.round(width / pixelRatio)
|
||||
}
|
||||
|
||||
export async function getImageSize (file: Blob): Promise<{ width: number, height: number, pixelRatio: number }> {
|
||||
const size = isPng(file) ? await getPngImageSize(file) : undefined
|
||||
|
||||
@ -65,20 +70,18 @@ async function getPngImageSize (file: Blob): Promise<{ width: number, height: nu
|
||||
const idhrData = parseIHDR(new DataView(iHDRChunk.data.buffer))
|
||||
const physData = parsePhys(new DataView(pHYsChunk.data.buffer))
|
||||
|
||||
if (physData.unit === 0 && physData.ppux === physData.ppuy) {
|
||||
const pixelRatio = Math.round(physData.ppux / 2834.5)
|
||||
return {
|
||||
width: idhrData.width,
|
||||
height: idhrData.height,
|
||||
pixelRatio
|
||||
}
|
||||
// Assuming pixels are square
|
||||
// http://www.libpng.org/pub/png/spec/1.2/PNG-Decoders.html#D.Pixel-dimensions
|
||||
const pixelRatio = Math.round(physData.ppux * 0.0254) / 72
|
||||
return {
|
||||
width: idhrData.width,
|
||||
height: idhrData.height,
|
||||
pixelRatio
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return undefined
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
// See http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
|
||||
|
@ -17,7 +17,7 @@
|
||||
<script lang="ts">
|
||||
import { type Space, type Class, type CollaborativeDoc, type Doc, type Ref } from '@hcengineering/core'
|
||||
import { IntlString, translate } from '@hcengineering/platform'
|
||||
import { getFileUrl, getImageSize } from '@hcengineering/presentation'
|
||||
import { getFileUrl, getImageSize, imageSizeToRatio } from '@hcengineering/presentation'
|
||||
import { markupToJSON } from '@hcengineering/text'
|
||||
import {
|
||||
AnySvelteComponent,
|
||||
@ -297,7 +297,7 @@
|
||||
type: 'image',
|
||||
attrs: {
|
||||
'file-id': attached.file,
|
||||
width: Math.round(size.width / size.pixelRatio)
|
||||
width: imageSizeToRatio(size.width, size.pixelRatio)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Markup } from '@hcengineering/core'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import presentation, { MessageViewer, getFileUrl, getImageSize } from '@hcengineering/presentation'
|
||||
import presentation, { MessageViewer, getFileUrl, getImageSize, imageSizeToRatio } from '@hcengineering/presentation'
|
||||
import { EmptyMarkup } from '@hcengineering/text'
|
||||
import textEditor, { RefAction } from '@hcengineering/text-editor'
|
||||
import {
|
||||
@ -257,7 +257,7 @@
|
||||
type: 'image',
|
||||
attrs: {
|
||||
'file-id': attached.file,
|
||||
width: Math.round(size.width / size.pixelRatio)
|
||||
width: imageSizeToRatio(size.width, size.pixelRatio)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -153,12 +153,15 @@ export const ImageExtension = ImageNode.extend<ImageOptions>({
|
||||
const fileName = node.attrs.alt ?? ''
|
||||
const fileType = node.attrs['data-file-type'] ?? 'image/*'
|
||||
|
||||
const metadata = node.attrs.width !== undefined ? { originalWidth: node.attrs.width } : {}
|
||||
|
||||
showPopup(
|
||||
FilePreviewPopup,
|
||||
{
|
||||
file: fileId,
|
||||
name: fileName,
|
||||
contentType: fileType,
|
||||
metadata,
|
||||
fullSize: true,
|
||||
showIcon: false
|
||||
},
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
import { setPlatformStatus, unknownError } from '@hcengineering/platform'
|
||||
import { getImageSize } from '@hcengineering/presentation'
|
||||
import { imageSizeToRatio, getImageSize } from '@hcengineering/presentation'
|
||||
import { Extension } from '@tiptap/core'
|
||||
import { Plugin, PluginKey } from '@tiptap/pm/state'
|
||||
import { type EditorView } from '@tiptap/pm/view'
|
||||
@ -41,6 +41,8 @@ function getType (type: string): 'image' | 'other' {
|
||||
* @public
|
||||
*/
|
||||
export const ImageUploadExtension = Extension.create<ImageUploadOptions>({
|
||||
name: 'image-upload',
|
||||
|
||||
addOptions () {
|
||||
return {
|
||||
getFileUrl: () => ''
|
||||
@ -157,7 +159,7 @@ async function handleImageUpload (
|
||||
src: url,
|
||||
alt: file.name,
|
||||
title: file.name,
|
||||
width: Math.round(size.width / size.pixelRatio)
|
||||
width: imageSizeToRatio(size.width, size.pixelRatio)
|
||||
})
|
||||
|
||||
const transaction = view.state.tr.insert(pos?.pos ?? 0, node)
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { type Blob, type Ref } from '@hcengineering/core'
|
||||
import { getBlobRef, type BlobMetadata } from '@hcengineering/presentation'
|
||||
import { getBlobRef, imageSizeToRatio, type BlobMetadata } from '@hcengineering/presentation'
|
||||
import { Loading } from '@hcengineering/ui'
|
||||
|
||||
export let value: Ref<Blob>
|
||||
@ -22,15 +22,20 @@
|
||||
export let metadata: BlobMetadata | undefined
|
||||
export let fit: boolean = false
|
||||
|
||||
$: p = getBlobRef(value, name)
|
||||
$: width = metadata?.originalWidth ? `min(${metadata.originalWidth / metadata?.pixelRatio ?? 1}px, 100%)` : '100%'
|
||||
$: height = metadata?.originalHeight
|
||||
? `min(${metadata.originalHeight / metadata?.pixelRatio ?? 1}px, ${fit ? '100%' : '80vh'})`
|
||||
: '100%'
|
||||
$: originalWidth = metadata?.originalWidth
|
||||
$: originalHeight = metadata?.originalHeight
|
||||
$: pixelRatio = metadata?.pixelRatio ?? 1
|
||||
|
||||
$: imageWidth = originalWidth != null ? imageSizeToRatio(originalWidth, pixelRatio) : undefined
|
||||
$: imageHeight = originalHeight != null ? imageSizeToRatio(originalHeight, pixelRatio) : undefined
|
||||
|
||||
$: width = imageWidth != null ? `min(${imageWidth}px, 100%)` : '100%'
|
||||
$: height = imageHeight != null ? `min(${imageHeight}px, ${fit ? '100%' : '80vh'})` : '100%'
|
||||
|
||||
let loading = true
|
||||
</script>
|
||||
|
||||
{#await p then blobRef}
|
||||
{#await getBlobRef(value, name) then blobRef}
|
||||
{#if loading}
|
||||
<div class="flex-center w-full h-full clear-mins">
|
||||
<Loading />
|
||||
|
Loading…
Reference in New Issue
Block a user