Getting an image from a GMap.NET.GMapControl without it being visible - c#

I would like to get a map from an online source (whether than be Google Maps, OpenStreetMap, or other) and be able to (1) display it on a form, and (2) save it as an image. These two functions are separate.
After a bit of research I concluded that the GMap.NET.GMapControl was probably the best way of doing this and I implemented this method. However, I have hit a snag when trying to save the image.
I am saving the image by generating a jpeg from the control using its ToImage() method. This works, but only when the map is visible on screen. In my application I need to be able to generate the image without rendering it to screen.
If the GMapControl is not visible, the jpeg is just a black rectangle. The test code below demonstrates this. The form contains two GMapControl controls. If both are visible I get two identical jpeg images. If one is hidden, the corresponding jpeg is blank.
Is there a way I can get the map image using a GMapControl without plotting it to screen? Or should I take a different approach and use something else? The more lightweight the better as far as I am concerned.
(My first attempt was using the WebBrowser control. I moved on from this because I was getting all the borders etc. as well as the map. I tried to exclude everything but the div containing the map, but then I lost everything ; I suspect this may have been because the map div was nested and I was hiding its parent...)
public partial class testForm : Form
{
public testForm()
{
InitializeComponent();
}
private void testForm_Shown(Object sender, EventArgs e)
{
gMapControl2.Hide(); // this results in a blank jpg image for gMapControl2
// Plot the same map to both gMapControls...
PlotMap(gMapControl1);
PlotMap(gMapControl2);
// Excuse the clunky wait method here ; it was due to a 'cross-thread' error when using the event raised by the gMapControl
// It serves the purpose here.
Task.Factory.StartNew(() => { Task.Delay(5000).Wait(); }).Wait(); // wait for 5 seconds to give maps plenty of time to render
WriteBitmap(gMapControl1, $#"E:\Test_gMapControl1.jpg");
WriteBitmap(gMapControl2, $#"E:\Test_gMapControl2.jpg");
}
private void PlotMap(GMapControl gMapControl)
{
gMapControl.MapProvider = GoogleMapProvider.Instance;
GMaps.Instance.Mode = AccessMode.ServerOnly;
gMapControl.ShowCenter = false;
gMapControl.MinZoom = 1;
gMapControl.MaxZoom = 25;
gMapControl.Zoom = 10;
gMapControl.Position = new PointLatLng(10, 10); // centered on 10 lat, 10 long
}
private void WriteBitmap(GMapControl gMapControl, string filename)
{
Image b = gMapControl.ToImage();
b.Save(filename, ImageFormat.Jpeg);
}
}

Related

How to property remove (or keep) the background and contents when exporting PDF to PNG using Magic.NET-Q16-AnyCPU

https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf
First time trying the Magic.NET-Q16-AnyCPU and I encounter an issue that I think I just do know the correct method to use I hope someone could lead me to get this corrected. I have a pdf with some existing texts and tables, plus a redline text added by using a pdf editing software.
Attached picture #1: depends on which software I use to view the png, some software shows black background. I like to have the background can show white or show as transparent (which is preferred) for all software. With page containing the red line text, it shows the red line one correctly but the other contents.
Attached picture #2: If I use settings.UseMonochrome = true; then this is no longer an issue but the resulting image I get is not what I prefer. I may sound stupid but with settings.UseMonochrome = false; my eyes feel better, especially when there are some graphics and tables.
Can I set settings. UseMonochrome = false; and still get all the contents shown correctly? And can I ensure the PNG background is either removed or set as White? Already try the image.BackgroundColor = MagickColors.White; but this does not impact the result.
private void button1_Click(object sender, EventArgs e)
{
var settings = new MagickReadSettings();
settings.Density = new Density(100, 100);
//Do not want to use this
//settings.UseMonochrome = true;
var filename = #"C:\Users\USER1\Desktop\dummy.pdf";
using (var images = new MagickImageCollection())
{
if(System.IO.File.Exists(filename))
{
images.Read(filename, settings);
var page = 1;
foreach (var image in images)
{
image.Write("C:\\Users\\USER1\\Desktop\\dummy.PNG");
page++;
}
}
}
}

Change the Background image to none then change back to default background image

So I am making code about changing The backgound image like:
button3.BackgroundImage = default;
button3.BackgroundImage = null;
But it does not work anyway. So the thing I need it to be is:
I Have 100 different buttons With Different images with randomized names
I Have checkbox1 Which will affect 100 buttons
if checked Then All background Images in 100 buttons will be None or null
if not checked then the 100 buttons will restore the default background image
Not using Some Method Like button1.BackgroundImage = System.Drawing.Image.FromFile(#"directory here"); because It will be so Long As I need to do it with 100 buttons
if you know how then reply
C# is an OO language so you should use it that way. The obvious option here is to create your own custom class that encapsulates this functionality, e.g.
public class ButtonEx : Button
{
private Image alternateBackgroundImage = null;
public void ToggleBackgroundImage()
{
(alternateBackgroundImage, BackgroundImage) = (BackgroundImage, alternateBackgroundImage);
}
}
You can then toggle all Buttons like so:
foreach (var btn in Controls.OfType<ButtonEx>)
{
btn.ToggleBackgroundImage();
}

How to draw GTK stock image inside DrawingArea

I'm writig a simple file browser in GTK#. I want to draw a stock image of a directory inside DrawingArea. I don't want to load external image. I came up to use Gdk.PixBuf but can't figure out how to load stock images.
There are a few ways of doing that, but I believe gtk_icon_theme_load_icon() is the one that is not deprecated and is compatible with most GTK+ versions. You will need a icon GtkIconTheme as a parameter, but in most cases gtk_icon_theme_get_default() is what you want. The icon name parameter is from Icon naming spec.
Ok, so rendering stock items inside DrawingArea is a bit ricky.
private Gdk.GC gc;
private Gdk.Pixbuf pixbuf;
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
Build ();
this.gc = new Gdk.GC((Gdk.Drawable)this.browserArea.GdkWindow);
//the method below does the trick. It is the only method I found that will return
//a valid pixbuf, so you can easily draw with the "usual" DrawPixbuf method in the
//ExposeEvent
this.pixbuf = RenderIcon(Gtk.Stock.Cdrom, IconSize.Dialog, "");
this.browserArea.ExposeEvent += new ExposeEventHandler(OnExposeEvent);
}
protected void OnExposeEvent(object sender, ExposeEventArgs args){
this.browserArea.GdkWindow.DrawPixbuf(this.gc, this.pixbuf,0,0,20,20,-1,-1,Gdk.RgbDither.None,0,0);
}

Winforms Listbox or Listview image and text

I'm not very experienced on c#. I'm working with winforms and I'm looking for a way to create something like a list of elements with this template , something like the autocompletion list of visual studio.
Is it possible to do? Shall I use listbox or listview?
EDIT
Sorry my question wasn't clear I don't want to create an autocomplete but what i want to create is something like this a list of things with an icon next to the text of that thing.
As I understand from your question, you can create custom UserControl or create a Form and put ListBox in it. If you use From be sure that you change border style layout, just set it to none. After creation for use it you should create form and show it where you want like this:
FrmAutoComplete x = new FrmAutoComplete();
x.Show();
you can put this form in ToolTipItem and show it.
Good luck.
THis is a quick and dirty example of using images in your Listview control. Since I don;t have a lot of information about what you plan to do, I tried to keep is simple.
In short, you need to load some images into one of the ImageLists (Large or Small) built into the Listview control and assign them keys so that you can assign them to specific list items as you add them.
The trick to this is determining which image to use for a specific list item (assuming there are different images assigned to different list items depending on some differentiating factor. For this example, I used an arbitrary assignment of "cars" or "trucks," and simply decided that the first five items in the list would be cars, and the last five would be trucks. I then assigned each image appropriately, using the image key as I added each listview item. You can do this for more complex scenarios, and when using the image key, it does not matter what order the items are added.
For this use case, you will want to create or use images with dimensions of 16 x 16 pixels. I went ahead and added two images to my project resource file, then simply accessed them using the project Properties.Resources name space. There are other ways to do this as well, but this is the most convenient for me.
Hope that helps.
public partial class Form1 : Form
{
static string CAR_IMAGE_KEY = "Car";
static string TRUCK_IMAGE_KEY = "Truck";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.SetupListview();
this.LoadListView();
}
private void SetupListview()
{
var imgList = new ImageList();
imgList.Images.Add("Car", Properties.Resources.jpgCarImage);
imgList.Images.Add("Truck", Properties.Resources.jpgTruckImage);
var lv = this.listView1;
lv.View = View.List;
lv.SmallImageList = imgList;
}
private void LoadListView()
{
for(int i = 1; i <= 10; i++)
{
string currentImageKey = CAR_IMAGE_KEY;
if(i > 5) currentImageKey = TRUCK_IMAGE_KEY;
var item = this.listView1.Items.Add("Item" + i.ToString(), currentImageKey);
}
}

Load image into picturebox only when needed/visible

I'm programming a little application that shows thumbnails of images. All the displayed images are in the same directory, each Image is inside it's own groupbox with a few labels and a checkbox. All the group boxes get added to a flowlayoutpanel. The problem is, that the amount of images may get pretty large and I'm concerned that memory usage / performance might get a little out of hand if I load all images even if they're not yet visible.
Is there a way to load only images that are currently visible to the user? My first thought is storing the location of my boxes and determine which images to load depending on the scroll position, or is there an easier way to determine if a picturebox/groupbox is currently visible?
Ideally what you should be doing is creating buffer logic rather than hiding 1 image and showing the other. It's a much better idea to have a couple buffers loading the images before you show them and have a fixed number of actual fields showing images rather than a new set per image.
But if your solution requires that, try to create a custom user control.
Try something like this:
public class customUserControl : UserControl
{
//Store image as a Uri rather than an Image
private Uri StoredImagePath;
public class PictureBoxAdv : PictureBox
{
public PictureBoxAdv()
{
this.VisibleChanged +=new EventHandler(VisibleChanged);
}
}
public Uri Image
{
get { return StoredImagePath; }
set
{
StoredImagePath = value;
if (this.Visible && StoredImagePath != null)
{
this.Image = Image.FromFile(StoredImagePath.AbsolutePath);
}
}
}
public void VisibleChanged(object sender, EventArgs e)
{
//When becomes visible, restore image, invisible, nullify.
if (this.Visible && StoredImagePath != null)
{
this.Image = Image.FromFile(StoredImagePath.AbsolutePath);
}
else
{
this.Image = null;
}
}
}

Categories