Support rotating image types

This commit is contained in:
martin 2024-11-07 04:06:48 +08:00
parent 2f06680f76
commit 304611073a
2 changed files with 34 additions and 18 deletions

View File

@ -57,7 +57,8 @@
<i-bs width="1em" height="1em" name="scissors"></i-bs>&nbsp;<span i18n>Split</span> <i-bs width="1em" height="1em" name="scissors"></i-bs>&nbsp;<span i18n>Split</span>
</button> </button>
<button ngbDropdownItem (click)="rotateDocument()" [disabled]="!userIsOwner || originalContentRenderType !== ContentRenderType.PDF"> <button ngbDropdownItem (click)="rotateDocument()"
[disabled]="!userIsOwner || (originalContentRenderType !== ContentRenderType.PDF && originalContentRenderType !== ContentRenderType.Image)">
<i-bs name="arrow-clockwise"></i-bs>&nbsp;<ng-container i18n>Rotate</ng-container> <i-bs name="arrow-clockwise"></i-bs>&nbsp;<ng-container i18n>Rotate</ng-container>
</button> </button>

View File

@ -212,30 +212,45 @@ def rotate(doc_ids: list[int], degrees: int):
qs = Document.objects.filter(id__in=doc_ids) qs = Document.objects.filter(id__in=doc_ids)
affected_docs = [] affected_docs = []
import pikepdf import pikepdf
from PIL import Image
rotate_tasks = [] rotate_tasks = []
image_mime_types = [
"image/png",
"image/jpeg",
"image/tiff",
"image/bmp",
"image/gif",
"image/webp",
]
for doc in qs: for doc in qs:
if doc.mime_type != "application/pdf": is_image = doc.mime_type in image_mime_types
if doc.mime_type != "application/pdf" and not is_image:
logger.warning( logger.warning(
f"Document {doc.id} is not a PDF, skipping rotation.", f"Document {doc.id} is not a PDF or image, skipping rotation.",
) )
continue continue
try: try:
with pikepdf.open(doc.source_path, allow_overwriting_input=True) as pdf: if is_image:
for page in pdf.pages: im = Image.open(doc.source_path)
page.rotate(degrees, relative=True) rotated = im.rotate(-degrees, expand=True)
pdf.save() format_from_mime = doc.mime_type.split("/")[1]
doc.checksum = hashlib.md5(doc.source_path.read_bytes()).hexdigest() dpi = im.info.get("dpi", None)
doc.save() save_kwargs = {"format": format_from_mime.upper()}
rotate_tasks.append( if dpi is not None:
update_document_archive_file.s( save_kwargs["dpi"] = dpi
document_id=doc.id, rotated.save(doc.source_path, **save_kwargs)
), else:
) with pikepdf.open(doc.source_path, allow_overwriting_input=True) as pdf:
logger.info( for page in pdf.pages:
f"Rotated document {doc.id} by {degrees} degrees", page.rotate(degrees, relative=True)
) pdf.save()
affected_docs.append(doc.id)
doc.checksum = hashlib.md5(doc.source_path.read_bytes()).hexdigest()
doc.save()
rotate_tasks.append(update_document_archive_file.s(document_id=doc.id))
logger.info(f"Rotated document {doc.id} by {degrees} degrees")
affected_docs.append(doc.id)
except Exception as e: except Exception as e:
logger.exception(f"Error rotating document {doc.id}: {e}") logger.exception(f"Error rotating document {doc.id}: {e}")