Hello,
I purchased an Aspose Python PSD OEM license to perform a specific task, but I’m unable to achieve the expected result. I need support to resolve this.
When I try to replace the content of a smart object, the result is not the same as in Photoshop. Here are the two images: the first one was generated with Photoshop, and the second one was generated using the Aspose.PSD Python library.
Below is the code I used to replace the content of the smart object.
# Import des classes Aspose.PSD nécessaires
from aspose.psd import Image, License
from aspose.psd.fileformats.psd import PsdImage
from aspose.psd.fileformats.psd.layers.smartobjects import SmartObjectLayer
from aspose.psd.imageoptions import JpegOptions
from aspose.psd.imageloadoptions import PsdLoadOptions
from aspose.pycore import cast
# ✅ 1. Appliquer la licence Aspose (si vous avez un fichier .lic)
try:
license = License()
license.set_license("Aspose.PSD.Python.NET.lic")
print("Licence appliquée avec succès.")
except Exception as e:
print(f"Erreur lors de l'application de la licence : {e}")
print("Continuation en mode d'évaluation...")
# ✅ 2. Charger le fichier PSD
load_options = PsdLoadOptions()
load_options.load_effects_resource = True
with Image.load("A.psd", load_options) as image:
# Cast vers PsdImage pour accéder aux layers
psd_image = cast(PsdImage, image)
found = False
# ✅ 3. Rechercher le Smart Object nommé "GC-COEUR"
print("Layers disponibles dans le PSD :")
print(f"Nombre de layers: {len(psd_image.layers)}")
for i, layer in enumerate(psd_image.layers):
layer_type = type(layer).__name__
layer_name = getattr(layer, 'display_name', 'N/A')
print(f" Layer {i}: {layer_name} (Type: {layer_type})")
if layer_name == "GC-COEUR":
print(f"Analyse détaillée du layer GC-COEUR:")
print(f" - Type direct: {type(layer)}")
print(f" - Attributs: {[attr for attr in dir(layer) if 'smart' in attr.lower()]}")
try:
smart_layer = cast(SmartObjectLayer, layer)
print(f" - Cast SmartObjectLayer réussi!")
print("Smart Object trouvé : GC-COEUR — édition du contenu interne...")
try:
print("Chargement du contenu existant du Smart Object...")
existing_content = smart_layer.load_contents(None)
print(f"Contenu existant: {type(existing_content)}, Taille: {existing_content.width}x{existing_content.height}")
print("Création d'un canvas basé sur le contenu existant...")
from aspose.psd import Graphics, Rectangle, Color
from aspose.psd.fileformats.psd import PsdImage as NewPsdImage
try:
canvas = NewPsdImage(existing_content.width, existing_content.height)
graphics = Graphics(canvas)
print("Préservation du contenu existant...")
dest_rect_base = Rectangle(0, 0, existing_content.width, existing_content.height)
graphics.draw_image(existing_content, dest_rect_base)
print("Ajout du logo par-dessus le contenu existant...")
with Image.load("logo.png") as logo:
print(f"Logo original: {logo.width}x{logo.height}")
canvas_width = existing_content.width
canvas_height = existing_content.height
print(f"Canvas: {canvas_width}x{canvas_height}")
max_width = int(canvas_width * 0.5)
max_height = int(canvas_height * 0.5)
logo_aspect = logo.width / logo.height
if logo.width > max_width or logo.height > max_height:
if max_width / logo_aspect <= max_height:
new_width = max_width
new_height = int(max_width / logo_aspect)
else:
new_height = max_height
new_width = int(max_height * logo_aspect)
else:
new_width = logo.width
new_height = logo.height
print(f"Logo redimensionné: {new_width}x{new_height}")
# Position centrée
x = (canvas_width - new_width) // 2
y = (canvas_height - new_height) // 2
print(f"Position du logo: x={x}, y={y}")
# Dessiner le logo PAR-DESSUS le contenu existant
logo_rect = Rectangle(x, y, new_width, new_height)
graphics.draw_image(logo, logo_rect)
print("Logo ajouté par-dessus le contenu existant.")
# Étape 4: Remplacer le contenu du Smart Object avec la composition
print("Mise à jour du Smart Object avec la composition (contenu + logo)...")
smart_layer.replace_contents(canvas)
# Étape 5: Mettre à jour pour préserver les transformations
print("Application des transformations...")
try:
smart_layer.update_all_modified_content()
print("Transformations appliquées avec succès.")
except Exception as update_ex:
print(f"Avertissement: {update_ex}")
print("Succès! Logo ajouté avec préservation du mockup original et des transformations.")
finally:
# Nettoyer les ressources
if 'graphics' in locals():
try:
graphics.dispose()
except:
pass
if 'canvas' in locals():
try:
canvas.dispose()
except:
pass
if 'existing_content' in locals():
try:
existing_content.dispose()
except:
pass
found = True
break
except Exception as ex:
print(f"Erreur lors du remplacement : {ex}")
print("Tentative avec le chemin de fichier...")
try:
smart_layer.replace_contents("logo.png")
print("Remplacement avec chemin de fichier réussi.")
found = True
break
except Exception as ex2:
print(f"Erreur lors du remplacement avec chemin : {ex2}")
except Exception as cast_ex:
print(f" - Cast SmartObjectLayer échoué: {cast_ex}")
print(f" - Ce n'est pas un Smart Object")
if isinstance(layer, SmartObjectLayer):
print(f" -> Smart Object détecté : {layer.display_name}")
if layer.display_name.lower() == "gc-coeur":
print("Smart Object trouvé : GC-COEUR — remplacement en cours...")
try:
layer.replace_contents("logo.png")
print("Remplacement réussi.")
except Exception as ex:
print(f"Erreur lors du remplacement : {ex}")
found = True
break
if not found:
print("Smart Object 'GC-COEUR' introuvable.")
# ✅ 4. Enregistrer le PSD modifié
psd_image.save("A_output.psd")
print("PSD sauvegardé sous 'A_output.psd'.")
# ✅ 5. Exporter en JPG
jpg_options = JpegOptions()
jpg_options.quality = 90 # qualité JPEG à 90%
psd_image.save("A_output.jpg", jpg_options)
print("JPG exporté sous 'A_output.jpg'.")
Photoshop-render.jpg (146,4 Ko)
AsPose-render.jpg (147,4 Ko)