I'd like to remove all the profile markers on one image, and also close all the corresponding profile images. Now I can use the code below to achieve that. But it contains two while loops to search all the images. Though it looks safe, but I'm afraid there is some bug. Is there any better way to achieve that?
Number close_profile_img(Image input_img, Number src_img_id, Number src_profile_comp_id)
{
Number derived_img_id, derived_profile_comp_id
if (!input_img.GetNumberNote("Private:Derived From", derived_img_id)) return 0
if (!input_img.GetNumberNote("Private:Component ID", derived_profile_comp_id)) return 0
if (derived_img_id == src_img_id && derived_profile_comp_id == src_profile_comp_id)
{
input_img.DeleteImage()
return 1
}
}
Void clear_profile(Image src_img)
{
Number k_profile = 12
ImageDisplay src_img_disp = src_img.ImageGetImageDisplay(0)
Number src_img_id = src_img.ImageGetID()
Component src_profile_comp
Number src_profile_comp_id
Image recurse_img
while (src_img_disp.ComponentCountChildrenOfType(k_profile) > 0)
{
src_profile_comp = src_img_disp.ComponentGetNthChildOfType(k_profile,0)
src_profile_comp_id = src_profile_comp.ComponentGetID()
recurse_img := GetFrontImage()
while (recurse_img.ImageIsValid())
{
if (close_profile_img(recurse_img, src_img_id, src_profile_comp_id))
{
src_profile_comp.ComponentRemoveFromParent()
break
}
else recurse_img := FindNextImage(recurse_img)
}
}
}
Image img := GetFrontImage()
clear_profile(img)
Overall, the script is pretty solid. Some things I've noticed:
You are not really recursive, so
recurse_imgis a misnomer.The "
GetFrontImage()/FindNextImage()" construct is slightly shaky because:It is possibly better to iterate over all ImageDocuments to find a match.
The script doesn't cater for the fact that you might have a profile but don't find a matching image. (This can happen if you open up data with a profile on it.) I think you want to remove the component always.
DeleteImage()is a bit outdated and also assumes a one-to-one match of image and imageDocument. I prefer to use the ImageDocument commands here.You forgot the return value in case of a non-match. This will give you an error during runtime.
With the above in mind, I would alter the script like this:
But you also asked for an alternative approach. Instead of looking through all images and check whether or not they belong to the profile, you can query the profile information on what image it corresponds to. As it is often the case, this additional information is found in a tagGroup associated with the object. For lineProfile components, it looks like this:
The first tag is used to identify groups of "mirrored" profile markers on different images, but the tagGroup specifies a Global Image ID referring to the profile image.
So, the script can look like this: