Mathematica : Add text to imported image / graphic as a label - image

Ive searched for hours ... but Im at a loss !
I have imported an image int Mathematica -> dimensions 2x2cm at 72DPI.
I am trying to "label" the image with a text string that:
- has font color "fontColor"
- has a black outline, so it contrasts to any underlying color
- sits in the bottom right corner of the imported image
- has size h/w in cm
- optionally sits in a text box with a white background
This is how far ive come:
MathCode:
image = Import["myimg.jpg"];
inchFactor = 2.54;(* 1 inch = 2.54cm *)
docRes = 72;
pixelConverter = docRes/inchFactor/2;
myText = First[
First[ImportString[
ExportString[
Style["glorious label string here", Bold, FontSize -> 15,
FontFamily -> "Verdana"], "PDF"], "PDF",
"TextMode" -> "Outlines"]]];
myTextGraphic =
Graphics[{EdgeForm[Directive[Black, Thickness[0.01]]], White,
myText}, Background -> White,
ImageSize -> {10*pixelConverter, 2*pixelConverter}];
myTextGraphic = Rasterize[myTextGraphic];
combined = SetAlphaChannel[myTextGraphic, myTextGraphicAlphaVersion];
I found the above method (PDF wrapper) for the black outline of the text string.
I am adding an AlphaChannel to the graphic of the text string using a version of it that only uses black/white.
I then try to combine the images with Overlay.
As none of this seems to work concerning the outputted image size and positioning, Im kindly asking for help.
ThereĀ“s no need to "fix" that messy code.
Maybe you could point me to a script or tutorial - all I really want is to add and position a text string or text box to an underlying image.
Thanks a lot !

Have a look at this. There are other ways too.
img = Import["http://todayinsci.com/H/Hilbert_David/HilbertDavidThm.jpg"];
Column[{
img,
Text[Style["Professor Hilbert", Red]]
}]
imgCtr = Round[ImageDimensions[img]/2];
overlay = Framed[Graphics[{Text[Style["Professor Hilbert", Red, 9], imgCtr]},ImageSize-> {66, 14}], FrameStyle -> Green]
Overlay[{img, overlay}, Alignment -> Center]

It's late here so this is only the beginning of a solution for you but here's a simple way to add a text label to an image:
lbl = Graphics[Text[Style["Bottom", Red, Large]]]
which creates an image with the text 'Bottom' in red in a large font. Next, given an image called img1
ImageCompose[img1,lbl]
puts the text in the centre of the image. ImageCompose has options to allow you to position the second image (ie the label) wrt the first image. You can put the label on a coloured background like this:
lbl = Graphics[Text[Style["Bottom", Red, Large, Background -> Blue]]]
I haven't figured out, yet, how to write the text with a coloured outline.

Related

Solving Overlapping Images when zooming in Codenameone

I have an imageviewer with a couple images, When i zoom in the first image and wanna see the right side of the image. The folowing image is overlapping the inzooming image. This is very annoying. Is there a way how i can set the zoom in image on the front.
How can i set the zoomed image always on front.
See picture https://i.stack.imgur.com/5f5JZ.jpg
My imageviewer is in a container
Image red ;
red = EncodedImage.create("/HW_Delfzijl_Waddenzee_Oost.jpg");
Image blue = Image.createImage(500, 500, 0xff0000ff);
Image red2 = Image.createImage(500, 500, 0xffff0000);
Image List1[]= new Image [3];
List1[0] = red;
List1[1] = blue;
List1[2] = red2;
iv = new ImageViewer();
iv.setWidth(500);
iv.setHeight(500);
iv.setImageList(new DefaultListModel<>(List1));
Container1 = BoxLayout.encloseY( Kaarten.AuvHW, AdvSpr,iv,
Up,progressbar);
I was able to reproduce this with the following code:
Form hi = new Form("ImageViewer", BoxLayout.y());
Image red = Image.createImage(2000, 800, 0xffff0000);
Image blue = Image.createImage(2000, 500, 0xff0000ff);
ImageViewer viewer = new ImageViewer();
viewer.setImageList(new DefaultListModel<>(red, blue));
hi.add(BoxLayout.encloseY(viewer, new Label("Dummy")));
hi.show();
The problem only happens if I stand on the blue image (the second one) scale it up and then try to move. It doesn't happen when moving from the red image to the blue.
I believe this is due to this method in the ImagaViewer code. Since background isn't painted the old image isn't cleaned up. We need to add a condition that disables that while dragging. I think changing the code in that method to this will fix the problem but it's a bit risky and might trigger flickering:
protected void paintBackground(Graphics g) {
// disable background painting for performance when zooming
if(imageDrawWidth < getWidth() || imageDrawHeight < getHeight() || panPositionX != 0) {
super.paintBackground(g);
}
}
I would suggest filing an issue so we can consider the options here as this isn't trivial. One partial workaround is to use:
viewer.setImageInitialPosition(ImageViewer.IMAGE_FILL);
Which minimizes the impact of the issue.

Moviepy - Place textclips at relative position

How do I place a textclip, right below the other? I require to place an image at the left of the video and two lines of text to the right of image, that are placed one below the other.
Something like this:
I tried to use set_position, but doesn't scale well for different videos (of different resolutions). By adjusting the arguments of set_position, I am able to place the textclips one below the other without gap in one resolution, but when I go to a higher resolution video, it shows a gap (I understand why the gap comes, but not sure how to prevent it)
txt_clip1 = TextClip("This is line 1 of text", fontsize = 12, color = 'white', bg_color='black')
txt_clip1 = txt_clip1.set_duration(7).set_start(0).set_end(7)
txt_clip1 = txt_clip1.set_position((0.1,0.90), relative=True).set_opacity(0.6)
txt_clip2 = TextClip("This is line 2 of the text, smaller font", fontsize = 8, color = 'white', bg_color='black')
txt_clip2 = txt_clip2.set_duration(7).set_start(0).set_end(7)
txt_clip2 = txt_clip2.set_position((0.1,0.93), relative=True).set_opacity(0.6)
I tried to insert a new line character in the text, but that doesn't suit me because the second line of text has different font properties.
Hopefully this will help you
txt_clip1 = TextClip(
"Cool effect 2nd line", color="black", bg_color="red", font="Amiri-Bold", kerning=5, fontsize=20
)
cvc = CompositeVideoClip([txt_clip1.set_position("East")], size=screensize)
txt_clip1 = txt_clip1.set_position((5,35))
.set_position mother take to arguments 1st is the position from the left screen and second is the position from the top
so your code is like something
txt_clip1 = txt_clip1.set_position((5,500))
txt_clip2 = txt_clip2.set_position((5,535))
It will place the text in the position you want.
Hopefully, this will help.
Happy coding

Remove any spacing, padding, and margin so a cell is filled completely with iText 7

How do I make a table in iText 7 with cells that don't have any spacing, padding, or margins on the inside. When I put an image in the cell it needs to fill the cell to 100%, touching the borders without any space of any kind at all.
I tried adding this to my Cell:
Cell qrImageCell = new Cell();
qrImageCell.setMargin(0f);
qrImageCell.setPadding(0f);
qrImageCell.setHeight(44f);
qrImageCell.add(barcodeImage.setMargins(0f,0f,0f,0f).setPadding(0f));
I also tried setting it in the table itself:
table.setPadding(0f);
table.setMargin(0f);
But whatever I try there is always a white rectangular area between the QR Code and the border (FYI: I would of course remove the border once it works.
Test with iText 7.1.15
With this image:
And this code:
Table table = new Table(1);
Image barcodeImage = new Image(ImageDataFactory.create("image.png"));
Cell qrImageCell = new Cell();
qrImageCell.setBorder(new SolidBorder(ColorConstants.RED, 2));
qrImageCell.setPadding(0f);
qrImageCell.add(barcodeImage);
table.addCell(qrImageCell);
doc.add(table);
The resulting output is:
Potential causes
Incorrect height
You have qrImageCell.setHeight(44f) in your code. Maybe that height does not correspond correctly with the height of your image. It's unlikely though that this is the problem, because it would not increase the width of the cell.
Impact of other cells
Making the table of the test above a 2-column table and adding a few cells shows that the size of the cells in the same row and column will have an impact on the size of the cell.
table.addCell(new Cell().add(new Paragraph("cell (1,2)")).setHeight(300));
table.addCell(new Cell().add(new Paragraph("cell (2,1)")).setWidth(300));
table.addCell(new Cell().add(new Paragraph("cell (2,2)")));
It's also unlikely that this is the problem, because in your output the image is centered in the cell.
There is no white space
Maybe the white "margins" are simply part of your barcode image. In that case, there isn't any spacing, margin or padding, but it would visually seem so.
Verify your input image or set a background color for the cell, so you can verify whether the white area is part of the image or part of the cell: qrImageCell.setBackgroundColor(ColorConstants.GREEN)
In the end the backgroundcolor trick helped me a lot. In the end the QR Image which is also generated by iText7 for some reason has a white border around itself. It's generated by this code:
BarcodeQRCode qrCode = new BarcodeQRCode(text);
PdfFormXObject barcodeObject = qrCode.createFormXObject(ColorConstants.BLACK, pdfDoc);
Image barcodeImage = new Image(barcodeObject).setPadding(0f).scaleAbsolute(44f, 44f)
But indeed setting the padding to "0f" removes any padding in the cell. Just have to find out if there's a possibility to remove that border around the QR code.

PIL: Imageobject.save() after drawing completely corrupts images and smurfs the ouput

I have these two functions in my program:
def depict_ph_increase(x,y,color, imobject):
program_print(color)
draw = PIL.ImageDraw.Draw(imobject)
draw.text((x, y),color,(255,255,255))
imobject.save('tmp-out.gif')
im_temp = PIL.Image.open("tmp-out.gif")#.convert2byte()
im_temp = im_temp.resize((930, 340), PIL.Image.ANTIALIAS)
MAP_temp = ImageTk.PhotoImage(im_temp)
map_display_temp = Label(main, image=MAP_temp)
map_display_temp.image = MAP_temp # keep a reference!
map_display_temp.grid(row=4,column=2, columnspan=3)
def read_temp_pixels(temperature_file, rngup, rngdown):
temp_image_object = PIL.Image.open(temperature_file)
(length, width) = get_image_size(temp_image_object)
(rngxleft, rngxright) = rngup
(rngyup,rngydown) = rngdown
print 'the length and width is'
print length, width
hotspots = 5;
for hotspot in range(0,hotspots):
color = "#ffffff"
while color == "#ffffff" or color == "#000000" or color == "#505050" or color == "#969696":
yc = random.randint(rngxleft, rngxright)
xc = random.randint(rngyup,rngydown)
color = convert_RGB_HEX(get_pixel_color(temp_image_object, xc, yc))
depict_ph_increase(xc,yc,color, temp_image_object)
The bottom one calls the top one. Their job is to read in this image:
It then randomly selects a few pixels, grabs their colors, and writes the hex values of the colors on top. But, when it redisplays the image, it gives me this garbage:
Those white numbers up near the upper right corner are the hex values its drawing. Its somehow reading the values from the corrupted image, despite the fact that I don't collect the values until AFTER I actually call the ImageDraw() method. Can someone explain to me why it is corrupting the image?
Some background--the get_pixel_color() function is used several other times in the program and is highly accurate, its just reading the pixel data from the newly corrupted image somehow. Furthermore, I do similar image reading (but not writing) at other points in my code.
If there is anything I can clarify, or any other part of my code you want to see, please let me know. You can also view the program in its entirety at my github here: https://github.com/jrfarah/coral/blob/master/src/realtime.py It should be commit #29.
Other SO questions I have examined, to no avail: Corrupted image is being saved with PIL
Any help would be greatly appreciated!
I fixed the problem by editing this line:
temp_image_object = PIL.Image.open(temperature_file)
to be
temp_image_object = PIL.Image.open(temperature_file).convert('RGB')

How to place my logo on my map without white fields?

I have a problem with the my picturebox.
I want to place it on my map which i got in my program.
That works when i put my img in a Picturebox and then BringToFront();
i wanted to add a picture with the problem, but i just started at StackOverflow and doesnt have enough reputation yet... :(
Anyway my img got displayed but with the white fields around it. The img I use doenst have these white stuff around it.
How can i make my Picturebox transparent so that the white fields get removed.
LogoBox.Location = new Point(size.Width - 340, size.Height - 100);
LogoBox.Image = Properties.Resources.Troepoet;
LogoBox.Size = new System.Drawing.Size(250, 40);
LogoBox.SizeMode = PictureBoxSizeMode.StretchImage;
LogoBox.BackColor = Color.Transparent;
I tried to do it with only drawing a bitmap aswell but then i cant see any possibility to place it on the map. The map is a 'dominant' control.
Any help/suggestions?
Thx.
You don't need to put a picturebox on the map to draw your logo.
The easy way is to override the Map OnPainOverlays() and draw whatever you want (Logo, Text, any shape) on the map or another way if you don't want to inherit the GmapControl and work with the GMapControl by drag & drop it over a form to handle the Paint() Event:
Private Sub GMapControl1_Paint(sender As Object, e As PaintEventArgs) Handles GMapControl1.Paint
Dim logo As Image = image.FromFile("C:\transparentLogo.png")
e.Graphics.DrawImage(logo, GMapControl1.Width - logo.Width - 5, 5, logo.Width, logo.Height)
End Sub
Make sure you make image transparent and save it as PNG format.

Resources