Files
Lyndon 0e0aee4328 Einzelunterschrift in eigenem Popup
Unterschriftenwarnung kommt nicht mehr bei nicht abrechenbaren Leistungen/Kategorien
2025-11-14 14:30:41 +01:00

87 lines
2.9 KiB
JavaScript

function trimCanvas(canvas) {
const context = canvas.getContext("2d", {willReadFrequently: true});
const imgWidth = canvas.width;
const imgHeight = canvas.height;
const imgData = context.getImageData(0, 0, imgWidth, imgHeight).data;
// Die Grenzen der nichtweißen Schrift ermitteln:
const cropTop = scanY(true, imgWidth, imgHeight, imgData);
const cropBottom = scanY(false, imgWidth, imgHeight, imgData);
const cropLeft = scanX(true, imgWidth, imgHeight, imgData);
const cropRight = scanX(false, imgWidth, imgHeight, imgData);
// Ein Pixel muss hinzugefügt werden, da es n + 1 Pixel zwischen Ziffern gibt:
const cropXDiff = (cropRight - cropLeft) + 1;
const cropYDiff = (cropBottom - cropTop) + 1;
// Die Bilddaten holen:
const trimmedData = context.getImageData(cropLeft, cropTop, cropXDiff, cropYDiff);
// Breite und Höhe der getrimmten Leinwand setzen:
canvas.width = cropXDiff;
canvas.height = cropYDiff;
// Leinwand leeren
context.clearRect(0, 0, cropXDiff, cropYDiff);
// Das Bild wird in die geleerte Leinwand gesetzt:
context.putImageData(trimmedData, 0, 0);
return canvas; // Zum Aneinanderreihen
}
// Erzeugt ein Rot-Grün-Blau-Alpha-Objekt mittels einer imgData-Koordinate und dessen Breite
function getRGBA(x, y, imgWidth, imgData) {
return {
red: imgData[(imgWidth * y + x) * 4],
green: imgData[(imgWidth * y + x) * 4 + 1],
blue: imgData[(imgWidth * y + x) * 4 + 2],
alpha: imgData[(imgWidth * y + x) * 4 + 3]
}
}
function getAlpha(x, y, imgWidth, imgData) {
return getRGBA(x, y, imgWidth, imgData).alpha;
}
// Ermittelt den nächsten nichtweißen Pixel.
function scanY(fromTop, imgWidth, imgHeight, imgData) {
const offset = fromTop ? 1 : -1;
const firstCol = fromTop ? 0 : imgHeight - 1;
// Zeilenweise Durchgehen
for(let y = firstCol; fromTop ? (y < imgHeight) : (y > -1); y += offset) {
// Spaltenweises Durchgehen
for(let x = 0; x < imgWidth; x++) {
// Wenn nicht weiß, gibt es die Spalte zurück
if(getAlpha(x, y, imgWidth, imgData)) {
return y;
}
}
}
// Das gesamte Bild ist bereits weiß
return null;
}
// Ermittelt die erste X-Koordinate in einem imgData-Objekt, die nicht weiß ist.
function scanX(fromLeft, imgWidth, imgHeight, imgData) {
const offset = fromLeft ? 1 : -1;
const firstRow = fromLeft ? 0 : imgWidth - 1;
// Spaltenweises Durchgehen
for(let x = firstRow; fromLeft ? (x < imgWidth) : (x > -1); x += offset) {
// Zeilenweise Durchgehen
for(let y = 0; y < imgHeight; y++) {
// Wenn nicht weiß, gibt es die Spalte zurück
if(getAlpha(x, y, imgWidth, imgData)) {
return x;
}
}
}
// Das gesamte Bild ist bereits weiß
return null;
}