Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   Есть знающие Inkscape? (https://javascript.ru/forum/offtopic/79191-est-znayushhie-inkscape.html)

laimas 01.01.2020 20:07

Есть знающие Inkscape?
 
Есть проблема. В браузере на страницу выводится изображение размером 2048х1367 с разрешением 96dpi для выделения на нем областей. Работа на странице производится с уменьшенным размером по ширине W = 1000.

1) для текущего DPI 96 размер пикселя в мм: mmpx = 2.5399931 / 96 = 0.0264583333
2) уменьшаем изображение на: aspectratio = 1000 / 2048 = 0.48828125
3) высота будет равна: H = 1367 * aspectratio = 667
4) отображаем размеры изображения в см: 2048 * mmpx = 54.19 / 1367 * mmpx = 36.17
5) рабочая область ограничена с краев на 2 см, узнаем ее в пикселях с учетом масштаба: 2 / mmpx * aspectratio = 37
6) расстояние между областями не должно быть меньше 1 см, в пикселях: 1 / mmpx * aspectratio = 18
7) делаем выделения и отображаем их координаты/размеры в см (с учетом масштаба), рассчитывая их: px * mmpx / aspectratio
8) если проверить и сделать одно выделение на всю рабочую область, то все верно с расчетами
9) сделали 4 выделения и передали их на сервер (в см), рассчитывая для SVG позицию по вертикали и от низа:

[
        {
            "x": 2,
            "y": 12.14,
            "y_svg": 5.99,
            "w": 7.04,
            "h": 18.04
        },
        {
            "x": 10.02,
            "y": 2.11,
            "y_svg": 2.09,
            "w": 15.01,
            "h": 31.97
        },
        {
            "x": 26.06,
            "y": 11.11,
            "y_svg": 7.07,
            "w": 15.01,
            "h": 17.99
        },
        {
            "x": 42.05,
            "y": 8.07,
            "y_svg": 16.72,
            "w": 10.08,
            "h": 11.38
        }
]


Создаем документ в Inkscape в пикселях 2048х1367, проверяем это в см, показывает 57,79911 х 38,57978, что уже не равно рассчитанному 54.19х36.17 (собственно для 96dpi размеры 57,79911 х 38,57978 не верны). Импортируем в документ изображение с разрешением считанном из него - изображение соответствует при этом рамкам документа. Но если расставить в нем сделанные выделения, то левая нижняя координата первого выделения с малой погрешностью по высоте становится на место, а вот ширина и высота его, если судить по изображению, не равна выделенному на клиенте. Отсюда начинают "плясать" и координаты/размеры остальных выделений.

Ошибка в расчетах на клиенте? Тогда бы и выделение всей рабочей области не соответствовало бы показаниям. Не верно встраивается изображение в документ Inkscape или не верно определяются свойства его документа, тогда как это верно сделать?

PS. Выделения в Inkscape расставляются так, что сверху и справа документа остается больше чем 2 см, то есть, выделения по размеру меньше оказываются, чем показываются на клиенте.

Malleys 02.01.2020 21:23

Цитата:

Сообщение от laimas
Не в интерполяции дело, да и к данной теме это не имеет отношения.

Как не имеет к теме отношения? Давай разбираться!

Цитата:

Сообщение от laimas
Создаем документ в Inkscape в пикселях 2048х1367, проверяем это в см, показывает 57,79911 х 38,57978, что уже не равно рассчитанному 54.19х36.17 (собственно для 96dpi размеры 57,79911 х 38,57978 не верны).

Всё верно, SVG-документ размером 2048×1367 единиц при 96 ppi будет иметь размеры ≈54.19×36.17 см, а при 90 ppi (которое очевидно используется в Inkscape) — ≈57.80×38.58см.

Ваши 2 сантиметра при различных значениях точек на дюйм (в данном случае нет никаких точек, а есть безразмерные единицы в пространстве SVG, так что грубо говоря, я считаю, что ваш 1 пиксель на растеризированной картинке раскрытой в полном размере соответствует 1 единице в SVG) будут иметь разные размеры в SVG — при 90 ppi будет ≈70.9 ед., при 96 ppi будет ≈75.6 ед. и при 300 ppi будет ≈236.2 ед.

S в SVG значит — масштабируемая. Единственное отношение, которое вы можете установить — использовать внутри SVG абстрактные единицы (добавив «px» при необходимости, чтобы CSS был верен), а затем установить ширину и высоту SVG в сантиметрах.

SVG не имеет никакого разрешения, это ведь векторная графика — SVG (Scalable Vector Graphics). Так что ваш SVG-документ может быть напечатан одинаково качественно и на маленькую марку, и на большой плакат на стене здания! Так что если вы хотите 2 см, вам нужно...
  • принять, что одна единица равна одному сантиметру
  • или пересчитать размер рамки в безразмерные единицы учитывая ppi
...и при печати использовать правильный размер бумаги — A2 в данном случае, а размер документа (≈54.19×36.17 см) указан в SVG.

Вот пример SVG размером 2048×1367 единиц, который отрисовывается на экране, занимая ≈1000×667.47 пикселей и имеет физический размер ≈54.19×36.17 см при разрешении 96 ppi...

Рамка нарисована на расстоянии 2 см (при 96 ppi) от краёв документа, а выделения мышкой рисуются в документ (devicePixelRatio нужен для правильного соответствия, когда страница отмасштабирована при помощи Ctrl+/-)! Также учтено, что документ при отрисовке может занимать меньшее место, как тут на форуме.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<style>
		html, body {
			background: #9CA3B1;
			width: 100%;
			height: 100%;
			display: grid;
			place-content: center;
			margin: 0;
		}
		svg {
			background: white;
			box-shadow: .1em .1em .5em .2em rgba(0, 0, 0, .3);
			cursor: crosshair;
			width: 90%;
			max-width: 1000px;
			display: inline-block;
			height: auto;
			margin: auto;
		}
		svg rect {
			pointer-events: none;
		}
		@media print {
			html, body {
				background: initial;
				display: initial;
			}
			svg {
				box-shadow: initial;
				width: auto;
				border: thin dashed rgba(0, 0, 0, 0.5);				
			}
		}
	</style>
</head>
<body>
	<svg
		xmlns="http://www.w3.org/2000/svg"
		version="1.1"
		id="canvas"
		fill="rgba(33, 150, 243, 0.25)"
		stroke="rgba(0, 0, 0, 0.5)"
	></svg>
	<script>
		const size = { width: 2048, height: 1367 };
		const ppi = 96;
		const ppcm = ppi / 2.54;

		canvas.setAttribute("width", `${size.width  / ppcm}cm`);
		canvas.setAttribute("height", `${size.height / ppcm}cm`);
		canvas.setAttribute("viewBox", [0, 0, size.width, size.height].join(" "));

		const borderRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
		borderRect.setAttribute("x", 2 * ppcm);
		borderRect.setAttribute("y", 2 * ppcm);
		borderRect.setAttribute("width",  size.width  - 4 * ppcm);
		borderRect.setAttribute("height", size.height - 4 * ppcm);
		borderRect.setAttribute("fill", "white");
		canvas.appendChild(borderRect);

		let activeRect = null;
		const event0 = {};

		canvas.addEventListener("pointerdown", event => {
			activeRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
			event0.screenX = event.screenX;
			event0.screenY = event.screenY;
			event0.offsetX = event.offsetX;
			event0.offsetY = event.offsetY;
			canvas.appendChild(activeRect);
		});
		addEventListener("pointermove", event => {
			if(!activeRect) return;
			
			const ρ = size.width / canvas.clientWidth;
			const α = 1 / devicePixelRatio;
			const Δx = event.screenX - event0.screenX;
			const Δy = event.screenY - event0.screenY;
			const x = Math.min(0, Δx * α) + event0.offsetX;
			const y = Math.min(0, Δy * α) + event0.offsetY;
			const width  = Math.abs(Δx) * α;
			const height = Math.abs(Δy) * α;

			activeRect.setAttribute("x", x * ρ);
			activeRect.setAttribute("y", y * ρ);
			activeRect.setAttribute("width", width * ρ);
			activeRect.setAttribute("height", height * ρ);
		});
		addEventListener("pointerup", event => {
			if(activeRect) activeRect = null;
		});
	</script>
</body>
</html>

laimas 02.01.2020 21:41

Malleys, вы читать умеете? Я же русским языком написал - почему импортируемое изображение в SVG с разрешением взятом у него (96dpi) в документе с установленном с этим же разрешением размеры изображения/документа не соответствуют физическим размерам изображения. Если я выделения сделанные расставлю в том же фотошоп, то хоть попиксельно проверяй, все встает на место, и размеры самого изображения не такие как Inksczpe показывает.

laimas 02.01.2020 22:12

Malleys, вы действительно полагаете, что вами написанное я читаю впервые? :)

Мне не нужно это читать, это дела давно прошедшие. Меня интересует не эта теория, а Inkscape, в нем как и в любом нормальном редакторе можно задать разрешение документа, ибо его как и любой иной можно на экране смотреть, а можно и распечатать.

Мне он в общем-то и не нужен для решаемой задачи, из этих выделений сервер сам готовит SVG оптимизированный. Назначение его, это маски на изображениях. Если эту маску приготовленную наложить на любое изображение с такими же отношениями сторон, то нет никаких проблем - как выделялось, так и работает. Более того, если в том же Inkscape руками подправить картинку и изменить размеры документа, на какие они и должны быть, а не те что он показывает, то и он сохранит без проблемную маску.

Вопрос возник потому, что есть идея еще кое-что добавить, что я и хотел в Inkscape проверить, и вот тут впервые обратил на это несоответствие внимание. Я нашел форум по Inkscape, если он не умер, то там спрошу, мне нужен тот кто хорошо знает эту программу, ибо есть еще вопросы по ней, которые мне важны.

laimas 02.01.2020 22:48

Цитата:

Сообщение от Malleys
Да, у вас нет времени читать!

Ну если бы вы были первооткрывателем этого и до вашего сообщения эта информация отсутствовала бы ... Нахрена мне это перечитывать, если я с этим давно знаком?

Цитата:

Сообщение от Malleys
Ни и какое разрешение у векторной графики?

Причем тут разрешение SVG если говорилось о разрешении документа и разрешении изображения вставляемого в него? Он принимает такое разрешение при импортировании в него изображения, откройте в конце концов программу, да ознакомтесь, к чему эти лишние вопросы.

Вы ее не знаете, к чему тогда разговор.

laimas 02.01.2020 23:44

Тот же самый. Вот меня и интересует откуда он могу считать иное разрешение изображения, чем я вижу и в свойствах, и в редакторах, слово есть еще какой-то подпольный EXIF, о котором только он и знает.

Malleys 02.01.2020 23:59

Цитата:

Сообщение от laimas
Тот же самый. Вот меня и интересует откуда он могу считать иное разрешение изображения, чем я вижу и в свойствах, и в редакторах, слово есть еще какой-то подпольный EXIF, о котором только он и знает.

Покажи файлик!

laimas 03.01.2020 00:32

Да что же вы такой упертый. Возьмите любой файл у себя. Учтите, работа с растровой графикой, а не векторной. В растре производится перерасчет выделений в сантиметры, так надо, а вставляться будет в пикселях.

Вот результат, который вы можете с любой картинкой наблюдать у себя:

верхнее, это то что покажет любой графический редактор, и это же самое получится если пересчитывать - пиксели в сантиметры. А вот Inkscape раст в сантиметры пересчитает по своему, отсюда и не совпадения.

Malleys 03.01.2020 01:15

Если открыть изображение (Сtrl+O), то перед его открытием всплывает диалоговое окно в котором спрашивается, с каким разрешением вы хотите его открыть? Очевидно вы даже не прочитав, что там написано, нажали OK!

Так вот, там 2 варианта, где Image DPI...
  • From File, выберите, если нужно как в файле
  • Default import resolution, выберите если нужно разрешение, указанное в Preferences.

В диалоговом окне Preferences (Shift+Ctrl+P) выберите слева раздел Bitmaps и укажите Default import resolution: 96 dpi. Также проверьте, стоит ли у вас галочка рядом с Ask about linking and scaling when importing, если нужно.

laimas 03.01.2020 01:26

Цитата:

Сообщение от Malleys
Очевидно вы даже не прочитав, что там написано, нажали OK!

Пипец какой-то. Я настолько дурной, что не понимаю что такое взять из файла, а почему жмахаю. Шел бы ты .... словоблуд.


Часовой пояс GMT +3, время: 13:03.