PLEASE ,
HOW CAN I DO IT " COPY RASTER IMAGE FROM LINKED FILE TO CURRENT FILE"
Hi Anas, welcome
You have certainly picked a non-trivial task for your first forum post - so I will run you through what you need to do.
Firstly, you cannot do this with OOTB nodes -or- with common packages, and there’s a reason for this - it’s not possible to insert images without loading them from a file (Revit can do it but it is not exposed in the API)
OK, onto the solution
- Get linked documents - I am using a dictionary so you can choose using the document title
import clr
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
OUT = {doc.Title: doc for doc in app.Documents if doc.IsLinked}
- Get Images - Once again I am using a dictionary to get the image filenames to make selection easier
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
def get_all_elements_of_category(doc, cat):
if isinstance(cat, int):
cat = ElementId(cat)
elif hasattr(cat, "Id"):
cat = cat.Id
return (
FilteredElementCollector(doc)
.OfCategoryId(cat)
.WhereElementIsNotElementType()
.ToElements()
)
doc = UnwrapElement(IN[0])
cat = BuiltInCategory.OST_RasterImages
OUT = {ii.Name: ii for ii in get_all_elements_of_category(doc, cat)}
- Let’s check our image!
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import ImageInstance
def get_bitmap(img_inst):
if isinstance(img_inst, ImageInstance):
return img_inst.Document.GetElement(img_inst.GetTypeId()).GetImage()
OUT = get_bitmap(UnwrapElement(IN[0]))
- Insert the image into the current document (Finally, the meat and potatoes!). This is where it gets tricky - I am using a temporary file to save the bitmap and then loading that in and inserting. There’s a lot of
System.Drawing
mucking about to save the bitmap. There are 4 inputs
- The view
- The image (
ImageInstance
) - The insert location
- Check if we want to insert the image, just in case
import tempfile
import clr
clr.AddReference("System.Drawing")
from System.Drawing.Imaging import (
Encoder,
EncoderParameter,
EncoderParameters,
ImageCodecInfo,
)
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import (
XYZ,
BoxPlacement,
ImageInstance,
ImagePlacementOptions,
ImageType,
ImageTypeOptions,
ImageTypeSource,
)
def get_bitmap(img_inst):
if isinstance(img_inst, ImageInstance):
return img_inst.Document.GetElement(img_inst.GetTypeId()).GetImage()
def save_image(bitmap, filepath, codec="png"):
encoder = None
for ie in ImageCodecInfo.GetImageEncoders():
if codec in ie.CodecName.lower():
encoder = ie
break
if encoder:
encoder_params = EncoderParameters(1)
colour_depth = EncoderParameter(Encoder.ColorDepth, 24)
encoder_params.Param[0] = colour_depth
bitmap.Save(filepath, encoder, encoder_params)
return True
doc = DocumentManager.Instance.CurrentDBDocument
view = UnwrapElement(IN[0])
image = UnwrapElement(IN[1])
location = IN[2]
if isinstance(location, list) and len(location) == 3:
location = XYZ(*location)
else:
location = XYZ()
insert_image = IN[3] # True / False
# only import if we can
if insert_image and ImageInstance.IsValidView(view):
bitmap = get_bitmap(image)
with tempfile.NamedTemporaryFile(suffix=".png") as fp:
fp.close()
image_saved = save_image(bitmap, fp.name)
if image_saved:
type_options = ImageTypeOptions(fp.name, False, ImageTypeSource.Import)
placement_options = ImagePlacementOptions()
placement_options.PlacementPoint = BoxPlacement.TopLeft
placement_options.Location = location
TransactionManager.Instance.EnsureInTransaction(doc)
image_type = ImageType.Create(doc, type_options)
image_instance = ImageInstance.Create(
doc, view, image_type.Id, placement_options
)
TransactionManager.Instance.TransactionTaskDone()
OUT = image_instance
else:
OUT = "Image was not inserted"
Everything all together
Note: This will convert any image (or PDF) to a png file - so it will not re-link originals, just insert a snapshot.
I appreciate your help and thank you for it⭐ , and about Python I am not a big expert in it😅
I have put the codes as you told me but there are some errors
Note:I don’t know if i put the python script you give me in a right way
What ist he wraning on the Python node? Note that for code to work it needs to be run in the same version of Revit; you appear to be in an unsupported build (notice the node color) so most of the community won’t be able to directly help you.
ImageTypeSource
enumeration has been in the Revit API since Revit 2021, so are you in an earlier version? (I currently can only work with R2022+)
I had a look at the API from 2020 - you could change the code to work, however it looks like it just links the image and does not give the option to import. This may work, or you may have issue with the temporary file being deleted
My guess here is that IronPython is passing the BuiltInCategory
as an object
try changing line 17 to if isinstance(cat, (int, BuiltInCategory))
which I think will work