I have an application with GMap.Net showing various markers. I know how to take a screen shot of the current map and markers:
Dim sImageName As String = DateTime.Now.ToString(Format("yyyyMMdd-HHmmss")) & ".png"
Dim ThisMap As New Bitmap(Form2.myMap.Width, Form2.myMap.Height)
Form2.myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, Form2.myMap.Width, Form2.myMap.Height))
ThisMap.Save(sImagesFolder & sImageName)
What I would like to do is create an image for a selected marker. Instead of the image being the entire map shown on screen, it would center on the marker and show 100 pixels in each direction.
Does anyone know how to do that?
This is what I tried, but it gives me a blank image-- nothing shows up. I feel like this should be working...
Private Sub MyMap_OnMarkerClick(item As GMapMarker, e As Windows.Forms.MouseEventArgs) Handles myMap.OnMarkerClick
SelMarkerX = e.X
SelMarkerY = e.Y
Dim sImageName As String = DateTime.Now.ToString(Format("yyyyMMdd-HHmmss")) & ".png"
Dim ThisMap As New Bitmap(140,100)
myMap.DrawToBitmap(ThisMap, New Rectangle(SelMarkerX - 70, SelMarkerY - 50, 140, 100))
ThisMap.Save(sImagesFolder & sImageName)
End Sub
I just don't get it. If I write:
myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, 140, 100)
then I get what you might expect. I get the upper left corner of the existing map from 0 to 140 horizontally and 0 to 100 vertically. If I change it to this:
myMap.DrawToBitmap(ThisMap, New Rectangle(10, 0, 140, 100)
then I get 0 to 130 horizontally and not 10 to 140.
Well, I couldn't figure out how to do it with Gmap, so I wondered if I could crop it outside of Gmap and apparently that is common. Here is the code I used.
Dim ThisMap As New Bitmap(Form2.myMap.Width, Form2.myMap.Height)
Form2.myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, Form2.myMap.Width, Form2.myMap.Height))
ThisMap.Save(sImagesFolder & sImageName)
Dim LocX = SelMarkerX - 160 'x cord. of where crop starts
Dim LocY = SelMarkerY - 120 'y cord. of where crop starts
Dim CropW = 320 'Crop width
Dim CropH = 240 'Crop height
Dim CropRect As New Rectangle(LocX, LocY, CropW, CropH)
Dim OriginalImage = ThisMap
Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
Using grp = Graphics.FromImage(CropImage)
grp.DrawImage(OriginalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
CropImage.Save(sImagesFolder & sImageName)
End Using
Related
In a test UWP form I have a basic manipulation test, code below. It draws 3 circles on a CanvasControl and sets up translation and scaling manipulation.
When I test this on a touch screen it basically does what I expect, translating and zooming the circles based on the position of 2 fingers on the screen. But if I pinch down beyond a certain point, the image starts to oscillate very quickly between 2 extents and will very quickly cause the code to stop with an overflow.
I put the canvas control in a grid and tried doing the manipulation on the canvas control from the grid control, and it does not suffer from the same problem although the effect of zooming and panning does not seem correct.
So it looks like the effect of my code as is, is an iteration, where a manipulation causing a render transform change could cause another manipulation, and it goes in circles until it settles - or if there is a problem of precision, perhaps due to the distance between the touch points getting too small, the iteration diverges until overflow.
Is this expected? What is the correct way to do this?
Private WithEvents Canv As New CanvasControl
Private WithEvents gr As New Grid
Private Sub Canv_Draw(sender As CanvasControl, args As CanvasDrawEventArgs) Handles Canv.Draw
args.DrawingSession.DrawCircle(50, 50, 25, Windows.UI.Colors.Blue)
args.DrawingSession.DrawCircle(250, 250, 25, Windows.UI.Colors.Blue)
args.DrawingSession.DrawCircle(500, 500, 25, Windows.UI.Colors.Blue)
End Sub
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Content = gr
gr.Children.Add(Canv)
Canv.ManipulationMode = ManipulationModes.Scale Or ManipulationModes.TranslateX Or ManipulationModes.TranslateY
end sub
Private Sub Canv_ManipulationDelta(sender As Object, e As ManipulationDeltaRoutedEventArgs) Handles Canv.ManipulationDelta
Dim t As New TranslateTransform
t.X = e.Cumulative.Translation.X
t.Y = e.Cumulative.Translation.Y
Dim s As New ScaleTransform
s.ScaleX = e.Cumulative.Scale
s.ScaleY = e.Cumulative.Scale
s.CenterX = e.Position.X
s.CenterY = e.Position.Y
Dim g As New TransformGroup
g.Children.Add(s)
g.Children.Add(t)
Canv.RenderTransform = g
End Sub
The common way in UWP is to use CompositeTransform, it supports Scale, Skew, Rotate and Translate.
Please see the BasicInput sample, especially the forth scenario
For the zooming issue, you can avoid it by using the following way:
Public NotInheritable Class MainPage
Inherits Page
Private WithEvents Canv As New CanvasControl
Private WithEvents gr As New Grid
Private Sub Canv_Draw(sender As CanvasControl, args As CanvasDrawEventArgs) Handles Canv.Draw
args.DrawingSession.DrawCircle(50, 50, 25, Windows.UI.Colors.Blue)
args.DrawingSession.DrawCircle(250, 250, 25, Windows.UI.Colors.Blue)
args.DrawingSession.DrawCircle(500, 500, 25, Windows.UI.Colors.Blue)
End Sub
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Content = gr
gr.Children.Add(Canv)
Canv.ManipulationMode = ManipulationModes.Scale Or ManipulationModes.TranslateX Or ManipulationModes.TranslateY
End Sub
Private Sub Canv_ManipulationDelta(sender As Object, e As ManipulationDeltaRoutedEventArgs) Handles Canv.ManipulationDelta
Dim tran = Transform(sender)
tran.ScaleX = tran.ScaleX * e.Delta.Scale
tran.ScaleY = tran.ScaleY * e.Delta.Scale
'System.Diagnostics.Debug.WriteLine("tran.ScaleX =" + tran.ScaleX.ToString() + " tran.ScaleY =" + tran.ScaleY.ToString())
End Sub
Private Function Transform(sender As Object) As CompositeTransform
Dim rect = TryCast(sender, CanvasControl)
rect.RenderTransformOrigin = New Point(0.5, 0.5)
Dim tran As New CompositeTransform
If TryCast(rect.RenderTransform, CompositeTransform) IsNot Nothing Then
tran = DirectCast(rect.RenderTransform, CompositeTransform)
Else
rect.RenderTransform = New CompositeTransform()
End If
Return tran
End Function
' utility method
Private Function Boundary(value As Double, min As Double, max As Double) As Double
If value > max Then
Return max
ElseIf value < min Then
Return min
Else
Return value
End If
End Function
End Class
Screenshot:
Some useful information in that, in the meantime I found a tidy solution, which was to leave the CanvasControl in the grid, and take the manipulation events from the grid and change the rendertransform of the Canvas control, that way there is no recursion. It also means that the natural translation is not correct - but this is easy to fix by multiplying it by the cumulative scale, ie. the full manipulation code becomes:
Private Sub GerberCanvGrid_ManipulationDelta(sender As Object, e As ManipulationDeltaRoutedEventArgs) Handles GerberCanvGrid.ManipulationDelta
Dim sf As New ScaleTransform
sf.ScaleX = e.Cumulative.Scale
sf.ScaleY = e.Cumulative.Scale
sf.CenterX = e.Position.X
sf.CenterY = e.Position.Y
Dim tt As New TranslateTransform
tt.X = e.Cumulative.Translation.X * e.Cumulative.Scale
tt.Y = e.Cumulative.Translation.Y * e.Cumulative.Scale
ManipulationTransform = New TransformGroup
ManipulationTransform.Children.Add(sf)
ManipulationTransform.Children.Add(tt)
GerberCanv.RenderTransform = ManipulationTransform
End Sub
I'm trying to place a logo near the text in the header. I'm able to resize it. However, I'm having a very difficult time positionining it anywhere (preferaby LEFT and TOP) would work. here is the code I have. It dumps the image far int he left top corner and I have no idea how to move it. Do I have to convert it to shape before being able to move it?
Dim SHP As InlineShape
'Dim SHP As Shape
With w_Wrd.Selection
.Font.Reset
.Font.Bold = True
.Font.Color = wdColorBlack
.Font.Name = "Times New Roman"
.Font.Size = 14
.ParagraphFormat.Alignment = wdAlignParagraphCenter
.TypeText " Needs Assessment/Family Care Plan NA/FCP "
End With
Set SHP = w_Wrd.Selection.InlineShapes.AddPicture(FileName:="Q:\IS\CEDAR\letetrhead.png", _
LinkToFile:=False, _
SaveWithDocument:=True)
With SHP
.Height = InchesToPoints(0.8)
.Width = InchesToPoints(1.3)
.ConvertToShape
End With
I need the below macro to reference another sub change event to loop reference to the row number of the scroll bar, i and then adjust the cell Bi . So far I can only get 100 scroll bars to reference only B2
Sub Tester88()
Dim ScrollBar As Object
Dim rng As Range
Dim i As Long
Dim lastRow As Long
lastRow = 99 'Modify as needed this will be the last possible row to add a button
For i = 2 To lastRow Step 4
Set rng = ActiveSheet.Cells(i, 18) 'Column 3, row i
'## Create the button object and assign a variable to represent it
Set ScrollBar = ActiveSheet.ScrollBars.Add(1, 1, 1, 1)
'## use the btn variable to manipulate the button:
With ScrollBar
.Top = rng.Top
.Left = rng.Left
.width = rng.width
.height = rng.RowHeight
.Value = 1
.Min = 1
.Max = 100
.SmallChange = 1
.LargeChange = 10
.LinkedCell = "$B$2"
.Display3DShading = True
End With
Next
End Sub
It looks like you can just put the row in .LinkedCell instead of having it hardcoded. You've set it to a range of 1-100; keep in mind if you are using LinkedCell you are directly controlling the value of the cell, so if you are controlling data that has an existing set of values you need to either set the range (and the value) to the existing value of the cell, or have it as a cell that just shows the scroll bar value and use a formula referencing that cell for the final result you want.+
I've solved this task, so:
Sub Tester88()
Dim ScrollBar As Object
Dim rng As Range
Dim i As Long
Dim lastRow As Long
lastRow = 99 'Modify as needed this will be the last possible row to add a button
For i = 2 To lastRow Step 4
Set rng = ActiveSheet.Cells(i, 13) 'Column 3, row i
'## Create the button object and assign a variable to represent it
Set ScrollBar = ActiveSheet.ScrollBars.Add(1, 1, 1, 1)
'## use the btn variable to manipulate the button:
With ScrollBar
.Top = rng.Top
.Left = rng.Left
.Width = rng.Width
.Height = rng.RowHeight
.Min = 1
.Max = 100
.SmallChange = 1
.LargeChange = 1
.LinkedCell = "B" & i
End With
Next
End Sub
I'm not able to draw, i've already read tutorials, i can't find the problem.
I simply have a correct UI drawed by Glade. Then i want to draw, for example 50 drawing areas. So i create a Grid with 50 cells; for each cell there is a vertical box (with a drawing area and a label inside each one). But i can't seen anything drawed.
class collega_GUI:
def __init__(self):
try:
self.__builder = Gtk.Builder()
self.__builder.add_from_file('UI2.glade')
self.__Grid = Gtk.Grid()
self.__Grid.set_margin_left(20)
self.__Grid.set_margin_right(20)
self.__Grid.set_row_spacing(10)
self.__Grid.set_column_spacing(15)
self.__Grid.set_column_homogeneous(True)
self.__GridBox = self.__builder.get_object('box11')
self.__GridBox.pack_end(self.__Grid, 1, 1, 20)
indirizzi_ip = []
for i in range(50):
indirizzi_ip.append(str(i))
cpu_info = {}
for ip in indirizzi_ip:
cpu_info[ip] = dict()
left = 0
right = 0
for ip in indirizzi_ip:
cpu_info[ip]['drawing_area'] = Gtk.DrawingArea()
cpu_info[ip]['drawing_area'].set_size_request(100, 100)
cpu_info[ip]['drawing_area'].set_name(ip)
box = Gtk.VBox(False, 5)
box.add(cpu_info[ip]['drawing_area'])
label = Gtk.Label(ip)
box.add(label)
self.__Grid.attach(box, left, right, 1, 1) #object,left,right,top,bottom
cpu_info[ip]['drawing_area'].connect("draw", self.__draw)
label.show()
cpu_info[ip]['drawing_area'].show() #the draw should start now!
box.show()
# 5 drawing areas in a row
left += 1
if left == 5:
right += 1
left = 0
self.__builder.get_object('Azioni_Window').show()
Gtk.main()
except Exception as xe:
logging.error('%s' % str(xe))
sys.exit()
def __draw(self, widget, context):
context.set_source_rgb(0.9, 0, 0.1) #rosso
context.set_source_rgb(0.1, 0.9, 0) #verde
context.set_source_rgb(0.8, 0.7, 0) #giallo
context.set_source_rgb(0.8, 0.7, 0.8) #inattivo
context.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
context.fill()
if __name__=='__main__':
try:
UINX=collega_GUI()
except Exception:
sys.exit()
You're missing
self.__Grid.show()
And hence nothing in the grid is shown.
In general it's easier to just call show_all() on some top-level container rather than trying to remember to show() every individual widget.
I have seen answers to question of how to add text watermark to an existing PDF document using iTextSharp. My question is how can we do multiline text. Is there a way to do this without having multiple PdfContentByte defined. I have tried to insert a newline character with no luck.
Here is the code from the internet. I just added
pdfData.ShowTextAligned(Element.ALIGN_CENTER, editDate, (pageRectangle.Width / 2) + 100, (pageRectangle.Height / 2) - 100, 45);
as the second line to get the second line of the watermark, it works but uses same parameters (color, size, etc.) as the first.
iTextSharp.text.Rectangle pageRectangle = PDFreader.GetPageSizeWithRotation(1);
//pdfcontentbyte object contains graphics and text content of page returned by pdfstamper
PdfContentByte pdfData = stamper.GetOverContent(1);
//create fontsize for watermark
pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 120);
//create new graphics state and assign opacity
PdfGState graphicsState = new PdfGState();
graphicsState.FillOpacity = 0.2F;
//set graphics state to pdfcontentbyte
pdfData.SetGState(graphicsState);
//set color of watermark
pdfData.SetColorFill(iTextSharp.text.Color.BLUE);
//indicates start of writing of text
pdfData.BeginText();
//show text as per position and rotation
pdfData.ShowTextAligned(Element.ALIGN_CENTER, "E D I T E D" , (pageRectangle.Width / 2), (pageRectangle.Height / 2), 45);
pdfData.ShowTextAligned(Element.ALIGN_CENTER, editDate, (pageRectangle.Width / 2) + 100, (pageRectangle.Height / 2) - 100, 45);
//call endText to invalid font set
pdfData.EndText();