what is the difference between DeleteImage() and closeImage()? - dm-script

If I use DeleteImage() within a thread versus CloseImage(), there seems to be a difference - but I can only guess. Does anyone have a clear definition?
More detail:
Within the thread, an image A has an ROI. If the user deletes the ROI, I also want to close the image A, but still use it again later in the thread.
It seems that when I use A.deleteImage(), I have to redefine that image, whereas if I use A.CloseImage() - I don't.
It looks like that is what is happening, but if anyone knows for sure, please let me know.
Thanks

In order to undestand the commands you need to understand how memory objects are managed.
Anything will remain a valid memory object as long as there is a valid reference to it.
In case of images, this tanslates to:
An image will stay in memory as long as at least one of the following
is true:
The image is displayed on the screen
A script variable points to the image
Any other DM routine has a variable that points to the image
A single image can have multiple of the above conditions fulfilled at the same time. The only way to remove an image from memory is, to ensure all references to it are removed.
For displayed images this means to "close" the display. As a user, you would click the "X" of the window. The same functionality is invoked by the script command CloseImage(). Note that using this command on an image which isn't displayed, doesn't do anything. Note further, that closing an image does not remove any variables or their references to this image.
For script variables this mean you somehow have to "unlink" the variable from the image. (The opposite from using := to assing it.). This is done with the DeleteImage() command. Alternatively, one could also direclty assign the variable to the NULL-pointer as in img := NULL
For held references from DM there is nothing you can do, and you shouldn't. If a certain routine requires an image to be there, it will remain. You may be able to close the Display, but you can never remove it. That's why you can often 'find' images, and even show them using their label. Camera refernece images are a good example for this, but there are others as well.
Visually:
With the explanation given above, you should be able to understand the different behavior in the following examples:
void CloseTest( number ShowItFirst )
{
image img := realImage( "Test", 4, 100, 100 )
Result( "\n Assignment: Image is valid:" + img.ImageIsValid() )
if ( ShowItFirst )
{
img.ShowImage()
Result( "\n Displaying: Image is valid:" + img.ImageIsValid() )
}
img.CloseImage()
Result( "\n Closing: Image is valid:" + img.ImageIsValid() )
img.ShowImage()
Result( "\n Displaying: Image is valid:" + img.ImageIsValid() )
}
void DeleteTest( number ShowItFirst )
{
image img := realImage( "Test", 4, 100, 100 )
Result( "\n Assignment: Image is valid:" + img.ImageIsValid() )
if ( ShowItFirst )
{
img.ShowImage()
Result( "\n Displaying: Image is valid:" + img.ImageIsValid() )
}
img.DeleteImage() // This is the same as: img := NULL
Result( "\n Deleting: Image is valid:" + img.ImageIsValid() )
// img.ShowImage() // This fails, because image is no longer valid!
}
It should now also be clear, why one can use CloseImage( A ) but not DeleteImage( A ) for a displayed image of label A:
The first command only wants to close the image display of the image which is referenced by the label. The second, however, wants to 'unlink' the script variable from the image. But the label 'A' is not a script-variable!

Related

Apply Custom Layout to Image in DigitalMicrograph GMS3

I have an image in DigitalMicrograph GMS3 (v 3.21.1374.0) which i have applied a custom databar to (trying to learn how to do this via script here: add / apply custom databar to image in DigitalMicrograph GMS3)
I have a custom layout that I can add manually by doing the following:
Right click on the image
Hover on layout (in context menu)
Left click "Apply Layout..."
Select the custom layout in dialog that pops up (the one I want is called "CheckLayout")
Click OK
How do I do this with a script? I know how to get the image and the imagedisplay objects but that is as far as I get.
//main - get front image and apply custom layout
image Img := GetFrontImage()
imageDisplay imgDisplay = Img.ImageGetImageDisplay(0)
//apply custom layout to image here
Any ideas?
The layout is a property of an ImageDocument not an image. The correct way of doing this (provided there exists a layout of name 'MyLayout') is:
ImageDocument doc = GetFrontImageDocument()
doc.ImageDocumentApplyLayout("MyLayout")
You might additionally be interested in the commands:
void ImageDocumentApplyLayout( ImageDocument, String )
void ImageDocumentRemoveDatabar( ImageDocument )
Number ImageDocumentGetLayoutCount( ImageDocument )
String ImageDocumentGetLayoutName( ImageDocument, Number )
as used in
ImageDocument doc = GetFrontImageDocument()
number nLO = doc.ImageDocumentGetLayoutCount()
Result( "\n Layouts in document:" + nLO )
For( number i=0; i<nLO; i++)
{
string layoutName = doc.ImageDocumentGetLayoutName(i)
Result( "\n\t"+i+":"+layoutName)
}

Slider filtering edges by property (e.g., strength [0-1])

I am a newbie in Cytoscape js, is there an example of how to filter down all edges that has an attribute lower than a certain threshold (using a slider)?
Thank you!
The code bellow shows how to filter edges by an attribute, in this example weight using a variable named threshold. The elements variable will have the filtered edges.
var elements = cy.filter('edges[weight > ' + threshold + ']')
The slider callback method could be used to trigger this function, resulting in a filter controlled by a slider.
If you wish to remove those elements from the graph, the restore function could be useful to return them back before filtering the graph again. An snippet of a possible callback method is given bellow:
var filteredEdges = [];
sliderCalback(threshold) {
// putting back the previously removed edges
cy.recover(filteredEdges);
// filtering edges
filteredEdges = cy.filter('edges[weight> ' + threshold + ']');
// Removing filteredEdges from graph
cy.remove(filteredEdges);
}
More details on Cytoscape.js filter method can be found here, and selectors can be found here.

Mass export all images as individual JPEGs in InDesign?

I am new to Indesign. I have a file that contains images with Photoshop clipping paths. I want to export all the clipped images in a folder. I have tried doing the "Copy Links To" and it successfully exported the original images. However, I do not want the original images but the clipped images instead. Is there a way for me to export all the clipped images as JPEG and not the original linked image? In short, I want to export the images without their background. I hope I'm making sense. I have about 800-1000 images so a batch processing method would be highly appreciated.
I found this script from one of the posts here and modified it a bit to suit my needs. It appears to work in most of my INDD documents, but it fails in others. I wonder why. I sometimes get the error message that
Error string: null is not an object
Source: fileName = File ( rect.graphics[0].itemLink.filePath ).name;
I also noticed that it skips some objects and won't download all of the images. I guess it skips those that are not in rectangles.
test();
function test()
{
var myDoc = app.activeDocument,
apis = myDoc.allPageItems, rect, fileName;
while ( rect = apis.pop() )
{
if ( !(rect instanceof Rectangle) || !rect.graphics[0].isValid ){ continue;}
fileName = File ( rect.graphics[0].itemLink.filePath ).name;
fileName = fileName.replace( /\.[a-z]{2,4}$/i, '.jpg' );
app.jpegExportPreferences.exportResolution = 2400;
app.jpegExportPreferences.jpegQuality = JPEGOptionsQuality.MAXIMUM;
//give it a unique name
var myFile = new File ("C:/Users/RANFacistol-Mata/Desktop/Image Trial/"+ fileName);
rect.exportFile(ExportFormat.JPG, myFile);
}
}
Is there a way for me to modify this script such that instead of iterating through all the rectangles, I would iterate through all of the objects instead, much like clicking this next button
And then check if that object contains an image (jpg, tiff, psd, ai, eps). If it does, then I will export it as scripted above.
Thank you for your help!
You can traverse the links present inside the document with the following snippet, this will take less time as taken by the snippet above...
You can also get the type of link ('eps' or ' pdf' etc) with linkType attribute and filePath with 'filePath' attribute of each link object..
var theDoc = app.documents.item(0);
var theLinkLen = theDoc.links.length;
for(var i = 0; i < theLinkLen; ++i)
{
var link = theDoc.links.item(i);
alert("link name \"" + link.name + "\"" + " has type \"" + link.linkType + "\""+ " with filePath \"" + link.filePath + "\"");
}

save and close images without asking

I try to write some code to save and close top 7 images, as it is below, but when I execute the code, the DM still ask “Save changes to xxx before closing? What command or code I need to add then the code can automatically save the changes of top 7 images without any pop-up ask window. Thanks
image temp:=getfrontimage()
string imgname=getname(temp)
string currentpath, currentdirectory
if(!SaveAsDialog("Save As",imgname,currentpath))exit(0)
currentdirectory=pathextractdirectory(currentpath,2)
number i
string newname, startstring
for(i=0; i<7; i++)
{
image front:=getfrontimage()
string imgname=getname(front)
string thispath=pathconcatenate(currentdirectory, imgname)
saveasgatan(front, thispath)
hideimage(front)
closeimage(front)
}
If you want to remove an image from memory, you can delete it rather than close it. The following removes the front most image without prompting:
image img := GetFrontImage()
DeleteImage( img )
It is also good to know that image objects are the actual data array, but imageDocuments are the objects which are linked to file and window. It is therefore a command of the imageDocument class which is needed. To close an image (or rather it's imageDocument) without asking to save, you can use:
image img := GetFrontImage()
imageDocument iDoc = img.ImageGetOrCreateImageDocument()
iDoc.ImageDocumentClose( 0 ) // parameter is Boolean for "askToSave"
There is also a command to get you the front most imageDocument right away, so you may also use:
GetFrontImageDocument().ImageDocumentClose(0)

UIScrollView lazy loading of images to reduce memory usage and avoid crash

My app, using scrollview that loads multiple images with NSOperation (Max around 100sh). I tried to test it out on my ipod 2Gen and it crashes due to low memory on device, but works fine on ipod 4th Gen. On 2nd Gen, it crashes when it loads about 15-20 images. How should I handle this problem ?
You could load you images lazily. That means, e.g., just a couple of images at a time in your scroll view, so that you can animate to the next and the previous one; when you move to the right, e.g., you also load one more image; at the same time, you unload images that are not directly accessible anymore (e.g. those that have remained to the left).
You should make the number of preloaded image sufficiently high so that the user can scroll without waiting at any time; this also depends on how big those images are and where they come from (i.e., how long it takes to load them)... a good starting point would be, IMO, 5 images loaded at any time.
Here you will find a nice step by step tutorial.
EDIT:
Since the link above seems to be broken, here is the final code from that post:
-(void)scrollViewDidScroll:(UIScrollView *)myScrollView {
/**
* calculate the current page that is shown
* you can also use myScrollview.frame.size.height if your image is the exact size of your scrollview
*/
int currentPage = (myScrollView.contentOffset.y / currentImageSize.height);
// display the image and maybe +/-1 for a smoother scrolling
// but be sure to check if the image already exists, you can do this very easily using tags
if ( [myScrollView viewWithTag:(currentPage +1)] ) {
return;
}
else {
// view is missing, create it and set its tag to currentPage+1
}
/**
* using your paging numbers as tag, you can also clean the UIScrollView
* from no longer needed views to get your memory back
* remove all image views except -1 and +1 of the currently drawn page
*/
for ( int i = 0; i < currentPages; i++ ) {
if ( (i < (currentPage-1) || i > (currentPage+1)) && [myScrollView viewWithTag:(i+1)] ) {
[[myScrollView viewWithTag:(i+1)] removeFromSuperview];
}
}
}