How to open an image with annotations by script - annotations

How do I open an (dm4) image with annotations in a script in dm-script?
When a dm4 image has annotations (e.g. a scale bar or some text), this is displayed when I open the image via the menu (Ctrl + O). But when I open the same file in a script by openImage() they do not show up as shown below.
On the left there is the image opened via the menu, on the right is the exact same image opened by openImage(). It is missing the annotations.
The following example shows the same thing. The code adds text to an image, saves it and opens it again. The opened image does not show the annotations just as the images above:
String path = GetApplicationDirectory("current", 0);
path = PathConcatenate(path, "temp.dm4");
// get the current image
image img;
img.getFrontImage();
ImageDisplay display = img.ImageGetImageDisplay(0);
// add some test annotations
number height = img.ImageGetDimensionSize(1);
number padding = height / 100;
number font_size = height/10;
for(number y = padding; y + font_size + padding < height; y += font_size + padding){
Component annotation = NewTextAnnotation(padding, y, "Test", font_size);
annotation.componentSetForegroundColor(255, 255, 255);
display.ComponentAddChildAtEnd(annotation);
}
// save the current image
img.saveImage(path);
// show the saved image
image img2 = openImage(path);
img2.showImage();

You have a mistake in the second to last line.
By using = instead of := you are copying (the values only) from the opened image into a new image. You want to do
image img2 := openImage(path)
This is a rather typical mistake made when being new to scripting, because this is a "specialty" of the scripting language not found in other languages. It comes about because scripting aims to enable very simple scripts like Z = log(A) where new images (here Z) are created on-the-fly from processing existing images (here A).
So there needs to be a different operator when one wants to assign an image to a variable.
For further details, see the F1 help documentation here:
The same logic / source of bugs concerns the use of := instead of = when "finding" images, "creating new images" and cloning images (with meta data).
Note the differences when trying both:
image a := RealImage("Test",4,100,100)
ShowImage(a)
image b = RealImage("Test",4,100,100)
ShowImage(b)
and
image a := GetFrontImage()
a = 0
image b = GetFrontImage()
b = 0
and
image src := GetFrontImage()
image a := ImageClone( src )
showImage(a)
image b := ImageClone( src )
showImage(b)

Related

Document generator, different margins for certain pages

I am creating a document using MATLAB's mlreportgen.dom.*;
I would like to be able to set the first and last page of a document to have no margins. This way I can get images to fit right across the page.
I am having difficulties with this, see example code
import mlreportgen.dom.*;
d = Document('myreport', 'pdf');
open(d);
currentLayout = d.CurrentPageLayout;
pdfheader = PDFPageHeader();
p = Paragraph('Sample Traffic Data in Austin');
p.Style = [p.Style, {HAlign('left'), Bold(true), FontSize('12pt')}];
append(pdfheader, p);
currentLayout.PageHeaders = pdfheader;
currentLayout.PageMargins.Gutter = '0.0in';
currentLayout.PageMargins.Left = '0.0in';
currentLayout.PageMargins.Right = '0.0in';
close(d);
rptview(d.OutputPath);
So far, I have naively tried to add a page break and redefine margins with no success. It appears to use the margins that come last in the document.

How to get depth images from the camera in pyBullet

In pyBullet, I have struggled a bit with generating a dataset. What I want to achieve is to get pictures of what the camera is seeing: img = p.getCameraImage(224, 224, renderer=p.ER_BULLET_HARDWARE_OPENGL)
Basically: to get the images that are seen in Synthetic Camera RGB data and Synthetic Camera Depth Data (especially this one), which are the camera windows you can see in the following picture on the left.
p.resetDebugVisualizerCamera(cameraDistance=0.5, cameraYaw=yaw, cameraPitch=pitch, cameraTargetPosition=[center_x, center_y, 0.785])
img = p.getCameraImage(224, 224, renderer=p.ER_BULLET_HARDWARE_OPENGL)
rgbBuffer = img[2]
depthBuffer = img[3]
list_of_rgbs.append(rgbBuffer)
list_of_depths.append(depthBuffer)
rgbim = Image.fromarray(rgbBuffer)
depim = Image.fromarray(depthBuffer)
rgbim.save('test_img/rgbtest'+str(counter)+'.jpg')
depim.save('test_img/depth'+str(counter)+'.tiff')
counter += 1
I already run the following, so I don't know if it is related to the settings. p.configureDebugVisualizer(p.COV_ENABLE_DEPTH_BUFFER_PREVIEW, 1)
I have tried several methods because the depth part is complicated. I don't understand if it needs to be treated separately because of the pixel color information or if I need to work with the project matrixes and view matrixes.
I need to save it as a .tiff because I get some cannot save F to png errors. I tried playing a bit with the bit information but acomplished nothing. In case you asked,
# depthBuffer[depthBuffer > 65535] = 65535
# im_uint16 = np.round(depthBuffer).astype(np.uint16)
# depthBuffer = im_uint16
The following is an example of the the .tiff image
And to end, just to remark that these depth images keep changing (looking at all of them, then to the RGB and passing again to the depth images, shows different images regardless of being the same image. I have never ever seen something like this before.
I thought "I managed to fix this some time ago, might as well post the answer found".
The data structure of img has to be taken into account!
img = p.getCameraImage(224, 224, shadow = False, renderer=p.ER_BULLET_HARDWARE_OPENGL)
rgb_opengl = (np.reshape(img[2], (IMG_SIZE, IMG_SIZE, 4)))
depth_buffer_opengl = np.reshape(img[3], [IMG_SIZE, IMG_SIZE])
depth_opengl = far * near / (far - (far - near) * depth_buffer_opengl)
seg_opengl = np.reshape(img[4], [IMG_SIZE, IMG_SIZE]) * 1. / 255.
rgbim = Image.fromarray(rgb_opengl)
rgbim_no_alpha = rgbim.convert('RGB')
rgbim_no_alpha.save('dataset/'+obj_name+'/'+ obj_name +'_rgb_'+str(counter)+'.jpg')
# plt.imshow(depth_buffer_opengl)
plt.imsave('dataset/'+obj_name+'/'+ obj_name+'_depth_'+str(counter)+'.jpg', depth_buffer_opengl)
# plt.show()
Final Images:

Add rectangle as inline-element with iText

How do I add a rectangle (or other graphical elements) as inline-elements to an iText PDF?
Example code of what I'm trying to achieve:
foreach (Row r in entrylist)
{
p = new Paragraph();
p.IndentationLeft = 10;
p.SpacingBefore = 10;
p.SpacingAfter = 10;
p.Add(new Rectangle(0, 0, 10, 10)); <<<<<<<<< THAT ONE FAILS
p.Add(new Paragraph(r.GetString("caption"), tahoma12b));
p.Add(new Paragraph(r.GetString("description"), tahoma12));
((Paragraph)p[1]).IndentationLeft = 10;
doc.Add(p);
}
It's something like a column of text-blocks, of which each of them have (only a printed) checkbox.
I've tried various things with DirectContent, but it requires me to provide absolute X and Y values. Which I simply don't have. The elements should be printed at the current position, wherever that may be.
Any clues?
You need a Chunk for which you've defined a generic tag. For instance, in this example listing a number of movies, a snippet of pellicule is drawn around the year a movie was produced and an ellipse was drawn in the background of the link to IMDB.
If you look at the MovieYears example, you'll find out how to use the PdfPageEvent interface and its onGenericTag() method. You're right that you can't add a Rectangle to a Paragraph (IMHO that wouldn't make much sense). As you indicate, you need to draw the rectangle to the direct content, and you get the coordinates of a Chunk by using the setGenericTag() method. As soon as the Chunk is drawn on the page, its coordinates will be passed to the onGenericTag() method.

What is the right way to manage image assets for J2ME in NetBeans

I'm using NetBeans to develop a J2ME app that runs across many different devices. The app uses a lot of different image assets. Since the devices have different screen sizes, this means that I need to compile multiple binaries, each with different asset sizes.
So far, I've been using a manual process to control the assets. I have a directory consisting of a bunch of subdirectories, each corresponding to assets needed for a particular class of device. For example, I have one directory "320_240", that has assets sized for a 320x240 screen, and another "480_360", that has assets sized for a 480x360 screen. The files names are exactly the same as is the code that loads them. Before I compile, I just copy the proper files into the default package (under src).
This can obviously be improved. I already have different project configurations representing the different screen sizes, so I'd like to make the assets switch automatically, too. As a relative novice for NetBeans, I'm not sure what the best way to do this is.
FWIW, here's the best I've come up with yet:
Create asset. packages under src, where LABEL corresponds to the device class (e.g. "320_240", "480_360")
Put the images for each class into the proper src/asset/ directory
Create a static final String assetDir that gets set to "/asset//" according to the currently selected project config
Load the images using Image.creatImage(assetDir + "image.png")
For each configuration, only include the necessary asset directory in Project->Build->Sources Filtering (I think this is necessary to avoid storing the unused images in the compiled app, correct?)
This still feels a bit hokey, though. This has to be a common problem. Does anyone have a better solution?
Thanks!
If you are using lot of images, then the size of jar file will be increased. You can't install that jar in some low-end devices.
Just use one image and resize the image according to screen width and screen height.
To resize the image, use the below method.
public Image resizeImage(Image src, int screenHeight, int screenWidth) {
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
Image tmp = Image.createImage(screenWidth, srcHeight);
Graphics g = tmp.getGraphics();
int ratio = (srcWidth << 16) / screenWidth;
int pos = ratio / 2;
//Horizontal Resize
for (int index = 0; index < screenWidth; index++) {
g.setClip(index, 0, 1, srcHeight);
g.drawImage(src, index - (pos >> 16), 0);
pos += ratio;
}
Image resizedImage = Image.createImage(screenWidth, screenHeight);
g = resizedImage.getGraphics();
ratio = (srcHeight << 16) / screenHeight;
pos = ratio / 2;
//Vertical resize
for (int index = 0; index < screenHeight; index++) {
g.setClip(0, index, screenWidth, 1);
g.drawImage(tmp, 0, index - (pos >> 16));
pos += ratio;
}
return resizedImage;
}

Unable to programmatically set Graphic Location in crystal report

In Crystal Reports 2008, there's a "Graphic Location" image property where it can be set to a file path so when the report gets run, it uses the selected picture file instead of the one on the report. I tried setting this via the .NET API, but it's only working some of the time.
In the report itself, I've set Graphic Location to {#LogoPath}, then when I run the report via .NET API, I set {#LogoPath} to the filename of the picture. I've put the formula on the report itself, and it's indeed getting set to the correct filename, but the image on the report doesn't always update. It would consistently show up for some time, then consistently not show it again.
Here's what I ended up using, the code is in Delpi Prism. One of the awkward thing to deal with is if the image being replaced is different size to the image on the report, Crystal doesn't resize it correctly. The other problem was I needed to free the picture object manually otherwise Crystal sometimes doesn't display it on the report.
method SetShadingAndLogo(const AReport:ReportDocument);
var
LogoPath:String;
PicObj:PictureObject;
Logo:System.Drawing.Image;
PicRatio:Double;
ContWidth, ContHeight:Double;
ContainerRatio:Double;
NewDimension:Double;
PosAdj:Integer;
Scale:Double;
begin
for each Section:Section in AReport.ReportDefinition.Sections do
begin
for each RptObj:ReportObject in Section.ReportObjects do
begin
if RptObj.Name.StartsWith('LOGO', StringComparison.CurrentCultureIgnoreCase) and
(RptObj.Kind = ReportObjectKind.PictureObject) then
begin
//set to company logo
LogoPath := "C:\logo.jpg";
PicObj := RptObj as PictureObject;
if not System.IO.File.Exists(LogoPath) then
PicObj.ObjectFormat.EnableSuppress := true
else
begin
Logo := System.Drawing.Image.FromFile(LogoPath);
//work out the aspect ratios of the image and the container
PicRatio := Double(Logo.Width) / Double(Logo.Height);
//convert twips to pixels
//96 is the default dpi for Windows, but should really check Windows settings
//instead of hard coding
ContWidth := Double(TwipsToPx(PicObj.Width, 96));
ContHeight := Double(TwipsToPx(PicObj.Height, 96));
ContainerRatio := ContWidth / ContHeight;
// adjust the size of the container on the report to maintiain the original
// image's ratio
if PicRatio > ContainerRatio then
begin
// reset the vertical position to remain centred on the original location
// get the new height of the container (in pixels)
NewDimension := (ContWidth / Logo.Width) * Logo.Height;
// get the movement (in twips)
PosAdj := PxToTwips(Integer((ContHeight - NewDimension) / 2), Integer(Logo.VerticalResolution));
// adjust the position
PicObj.Top := PicObj.Top + PosAdj;
// picture is wider so adjust the height accordingly
// need to scale using the logo's dpi to resize correctly
Scale := Double(PicObj.Width) / Double(PxToTwips(Logo.Width, Integer(Logo.VerticalResolution)));
PicObj.Width := Integer(PicObj.Width * Scale);
PicObj.Height := Integer(PicObj.Height * Scale);
end
else
begin
// picture is taller and needs to be scaled to height
// reset the horizontal position to remain centred on the original location
// get the new width of the container (in pixels)
NewDimension := (ContHeight / Logo.Height) * Logo.Width;
// get the movement (in twips)
PosAdj := PxToTwips(Integer((ContWidth - NewDimension) / 2), Integer(Logo.VerticalResolution));
// adjust the position
PicObj.Left := PicObj.Left + PosAdj;
// picture is taller and needs to be scaled to height
// need to scale using the logo's dpi to resize correctly
Scale := Double(PicObj.Height) / Double(PxToTwips(Logo.Height, Integer(Logo.VerticalResolution)));
PicObj.Width := Integer(PicObj.Width * Scale);
PicObj.Height := Integer(PicObj.Height * Scale);
end;
//must free the logo, otherwise Crystal sometimes doesn't display it on report
Logo.Dispose;
for each fm:FormulaFieldDefinition in AReport.DataDefinition.FormulaFields do
begin
if fm.Name.Equals("LogoPath") then
fm.Text := """"+LogoPath+"""";
end;
end;
end;
end;
end;
end;
method TwipsToPx(const AValue, ADpi:Integer):Integer;
begin
//convert to twips using specified dpi, 96 is Windows' default dpi
Result := System.Convert.ToInt32(Double(AValue) * ADpi / 1440);
end;
method PxToTwips(const AValue, ADpi:Integer):Integer;
begin
//convert to pixels using specified dpi, 96 is Windows' default dpi
Result := System.Convert.ToInt32(Double(AValue) * 1440 / ADpi);
end;
Take a look at my Crystal Reports: Dynamic Images posting.
In Graphics Location formula, you might want to do like as follow:-
{?imageUrl}
You can set this parameter in your CS file dynamically by doing as follow:-
ParameterFields paramFields = new ParameterFields();
ParameterField paramField = new ParameterField();
ParameterDiscreteValue parameterValue = new ParameterDiscreteValue();
paramField.Name = "imageUrl";
parameterValue.Value = "**URL FOR IMAGE**";
paramField.CurrentValues.Add(parameterValue1);
paramFields.Add(paramField);
In Report, Create "imageUrl" Parameter field. By doing as follow :-
1) Go to report and open Field Explorer on your left. If its not there you can get it by going
Crystal Report >> Filed Explorer.
2) Right click on Parameter Field and click on "New"
3) Give Parameter name as "imageUrl". In "Value Option" set "Prompt With display only" and "Optional Prompt" to false.
This should work.
Let me know if it helps.