ngx-image-cropper 7.1.2 → 7.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/component/image-cropper.component.mjs +2 -2
- package/esm2020/lib/services/load-image.service.mjs +64 -34
- package/fesm2015/ngx-image-cropper.mjs +70 -31
- package/fesm2015/ngx-image-cropper.mjs.map +1 -1
- package/fesm2020/ngx-image-cropper.mjs +63 -33
- package/fesm2020/ngx-image-cropper.mjs.map +1 -1
- package/lib/services/load-image.service.d.ts +2 -1
- package/package.json +2 -1
|
@@ -618,29 +618,34 @@ class LoadImageService {
|
|
|
618
618
|
this.autoRotateSupported = supportsAutomaticRotation();
|
|
619
619
|
}
|
|
620
620
|
loadImageFile(file, cropperSettings) {
|
|
621
|
-
return
|
|
622
|
-
|
|
621
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
622
|
+
const arrayBuffer = yield file.arrayBuffer();
|
|
623
|
+
return yield this.checkImageTypeAndLoadImageFromArrayBuffer(arrayBuffer, file.type, cropperSettings);
|
|
624
|
+
});
|
|
623
625
|
}
|
|
624
626
|
checkImageTypeAndLoadImageFromArrayBuffer(arrayBuffer, imageType, cropperSettings) {
|
|
625
627
|
if (!this.isValidImageType(imageType)) {
|
|
626
628
|
return Promise.reject(new Error('Invalid image type'));
|
|
627
629
|
}
|
|
628
|
-
return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings);
|
|
630
|
+
return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings, imageType);
|
|
629
631
|
}
|
|
630
632
|
isValidImageType(type) {
|
|
631
|
-
return /image\/(png|jpg|jpeg|bmp|gif|tiff|webp|x-icon|vnd.microsoft.icon)/.test(type);
|
|
633
|
+
return /image\/(png|jpg|jpeg|bmp|gif|tiff|svg|webp|x-icon|vnd.microsoft.icon)/.test(type);
|
|
632
634
|
}
|
|
633
635
|
loadImageFromURL(url, cropperSettings) {
|
|
634
|
-
return
|
|
635
|
-
|
|
636
|
-
|
|
636
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
637
|
+
const res = yield fetch(url);
|
|
638
|
+
const blob = yield res.blob();
|
|
639
|
+
const buffer = yield blob.arrayBuffer();
|
|
640
|
+
return yield this.loadImageFromArrayBuffer(buffer, cropperSettings, blob.type);
|
|
641
|
+
});
|
|
637
642
|
}
|
|
638
643
|
loadBase64Image(imageBase64, cropperSettings) {
|
|
639
644
|
const arrayBuffer = this.base64ToArrayBuffer(imageBase64);
|
|
640
645
|
return this.loadImageFromArrayBuffer(arrayBuffer, cropperSettings);
|
|
641
646
|
}
|
|
642
647
|
base64ToArrayBuffer(imageBase64) {
|
|
643
|
-
imageBase64 = imageBase64.replace(/^data
|
|
648
|
+
imageBase64 = imageBase64.replace(/^data:([^;]+);base64,/gmi, '');
|
|
644
649
|
const binaryString = atob(imageBase64);
|
|
645
650
|
const len = binaryString.length;
|
|
646
651
|
const bytes = new Uint8Array(len);
|
|
@@ -649,24 +654,61 @@ class LoadImageService {
|
|
|
649
654
|
}
|
|
650
655
|
return bytes.buffer;
|
|
651
656
|
}
|
|
652
|
-
loadImageFromArrayBuffer(arrayBuffer, cropperSettings) {
|
|
653
|
-
return
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
657
|
+
loadImageFromArrayBuffer(arrayBuffer, cropperSettings, imageType) {
|
|
658
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
659
|
+
const res = yield new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
660
|
+
try {
|
|
661
|
+
const blob = new Blob([arrayBuffer], imageType ? { type: imageType } : undefined);
|
|
662
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
663
|
+
const originalImage = new Image();
|
|
664
|
+
const isSvg = imageType === 'image/svg+xml';
|
|
665
|
+
const originalImageSize = isSvg ? yield this.getSvgImageSize(blob) : undefined;
|
|
666
|
+
originalImage.onload = () => resolve({
|
|
667
|
+
originalImage,
|
|
668
|
+
originalImageSize,
|
|
669
|
+
originalObjectUrl: objectUrl,
|
|
670
|
+
originalArrayBuffer: arrayBuffer
|
|
671
|
+
});
|
|
672
|
+
originalImage.onerror = reject;
|
|
673
|
+
originalImage.src = objectUrl;
|
|
674
|
+
}
|
|
675
|
+
catch (e) {
|
|
676
|
+
reject(e);
|
|
677
|
+
}
|
|
678
|
+
}));
|
|
679
|
+
return yield this.transformImageFromArrayBuffer(res, cropperSettings, res.originalImageSize != null);
|
|
680
|
+
});
|
|
665
681
|
}
|
|
666
|
-
|
|
682
|
+
getSvgImageSize(blob) {
|
|
683
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
684
|
+
const parser = new DOMParser();
|
|
685
|
+
const doc = parser.parseFromString(yield blob.text(), 'image/svg+xml');
|
|
686
|
+
const svgElement = doc.querySelector('svg');
|
|
687
|
+
if (!svgElement) {
|
|
688
|
+
throw Error('Failed to parse SVG image');
|
|
689
|
+
}
|
|
690
|
+
const widthAttr = svgElement.getAttribute('width');
|
|
691
|
+
const heightAttr = svgElement.getAttribute('height');
|
|
692
|
+
if (widthAttr && heightAttr) {
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
const viewBoxAttr = svgElement.getAttribute('viewBox')
|
|
696
|
+
|| svgElement.getAttribute('viewbox');
|
|
697
|
+
if (viewBoxAttr) {
|
|
698
|
+
const viewBox = viewBoxAttr.split(' ');
|
|
699
|
+
return {
|
|
700
|
+
width: +viewBox[2],
|
|
701
|
+
height: +viewBox[3]
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
throw Error('Failed to load SVG image. SVG must have width + height or viewBox definition.');
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
transformImageFromArrayBuffer(res, cropperSettings, forceTransform = false) {
|
|
708
|
+
var _a;
|
|
667
709
|
return __awaiter(this, void 0, void 0, function* () {
|
|
668
710
|
const autoRotate = yield this.autoRotateSupported;
|
|
669
|
-
const exifTransform =
|
|
711
|
+
const exifTransform = getTransformationsFromExifData(autoRotate ? -1 : res.originalArrayBuffer);
|
|
670
712
|
if (!res.originalImage || !res.originalImage.complete) {
|
|
671
713
|
return Promise.reject(new Error('No image loaded'));
|
|
672
714
|
}
|
|
@@ -674,24 +716,21 @@ class LoadImageService {
|
|
|
674
716
|
original: {
|
|
675
717
|
objectUrl: res.originalObjectUrl,
|
|
676
718
|
image: res.originalImage,
|
|
677
|
-
size: {
|
|
719
|
+
size: (_a = res.originalImageSize) !== null && _a !== void 0 ? _a : {
|
|
678
720
|
width: res.originalImage.naturalWidth,
|
|
679
721
|
height: res.originalImage.naturalHeight
|
|
680
722
|
}
|
|
681
723
|
},
|
|
682
724
|
exifTransform
|
|
683
725
|
};
|
|
684
|
-
return this.transformLoadedImage(loadedImage, cropperSettings);
|
|
726
|
+
return this.transformLoadedImage(loadedImage, cropperSettings, forceTransform);
|
|
685
727
|
});
|
|
686
728
|
}
|
|
687
|
-
transformLoadedImage(loadedImage, cropperSettings) {
|
|
729
|
+
transformLoadedImage(loadedImage, cropperSettings, forceTransform = false) {
|
|
688
730
|
return __awaiter(this, void 0, void 0, function* () {
|
|
689
731
|
const canvasRotation = cropperSettings.canvasRotation + loadedImage.exifTransform.rotate;
|
|
690
|
-
const originalSize =
|
|
691
|
-
|
|
692
|
-
height: loadedImage.original.image.naturalHeight
|
|
693
|
-
};
|
|
694
|
-
if (canvasRotation === 0 && !loadedImage.exifTransform.flip && !cropperSettings.containWithinAspectRatio) {
|
|
732
|
+
const originalSize = loadedImage.original.size;
|
|
733
|
+
if (!forceTransform && canvasRotation === 0 && !loadedImage.exifTransform.flip && !cropperSettings.containWithinAspectRatio) {
|
|
695
734
|
return {
|
|
696
735
|
original: {
|
|
697
736
|
objectUrl: loadedImage.original.objectUrl,
|