chugathon
pet medications no prescription http://medsnoprescriptiononline.com/ california institute for regenerative medicine

Author Topic: Restrict zoom-out to "Fit"?  (Read 1762 times)

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Restrict zoom-out to "Fit"?
« on: September 11, 2017, 07:52:04 AM »
I want to make sure users cannot zoom out too far, i.e. "shrink" the image to a size smaller than the image box itself. I'm using ZoomToFit() to initialize the image, and I want to limit zooming-out to that factor.

Any simple way of achieving this?
« Last Edit: September 11, 2017, 07:56:09 AM by ruland »

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Re: Restrict zoom-out to "Fit"?
« Reply #1 on: September 11, 2017, 08:12:45 AM »
The solution I found so far is:

1. Get zoom factor after ZoomToFit:

        private void frmMain_Load(object sender, EventArgs e)
        {
            imgMap.ZoomToFit();
            AppData.SetMinZoom (imgMap.Zoom);
        }


2. Check in _ZoomChanged:

        private void imgMap_ZoomChanged(object sender, EventArgs e)
        {
            if (imgMap.Zoom < AppData.GetMinZoom())
                imgMap.Zoom = AppData.GetMinZoom();
       }

Not sure if this is the best way though.
« Last Edit: September 11, 2017, 08:15:05 AM by ruland »

Richard Moss

  • Cyotek Team
  • Administrator
  • Full Member
  • *****
  • Posts: 237
  • Karma: +16/-0
    • cyotek.com
Re: Restrict zoom-out to "Fit"?
« Reply #2 on: September 11, 2017, 05:51:12 PM »
Hello,

In regards to getting the best fit zoom factor unfortunately I didn't expose this via a method or property so there isn't a way of getting it, save what you're already doing.

However, I think we could expand the load handler a touch to avoid having to have zoom changed handler as no doubt there's a bit of jank when the zoom gets set and then reset.

The ImageBox control has a ZoomLevels property which is a collection of all the incremental values that will be used when zooming in or out. What you could do is find the minimum zoom factor, then remove all values lower than this, and then insert that minimum zoom factor to the start of the list. That should then prevent ImageBox from automatically zooming beyond this.

Give that a go and let me know if it works, if so perhaps I'll add a FAQ entry or expand the demo.

Although this doesn't sound like quite the same issue, you could also check this issue on GitHub which has some sample code and may be of interest.

Regards;
Richard Moss

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Re: Restrict zoom-out to "Fit"?
« Reply #3 on: September 12, 2017, 08:49:13 AM »
Thanks a lot for that tip. However, I guess I'm doing it wrong.
Here is what I'm trying after loading a new image:

Quote
            LoadImage();                     // Load a new image to ImageBox
            imgMap.ZoomToFit();              // Zoom out to fit image

            int zoomlevel;
            for (int level = 0; level < imgMap.ZoomLevels.Count;  level++)
                {
                zoomlevel = imgMap.ZoomLevels[level];
                if (zoomlevel < imgMap.Zoom)
                {
                    imgMap.ZoomLevels[level] = imgMap.Zoom;
                }
            }

Unfortunately modifying the first list element (imgMap.ZoomLevels[0]) only removes this element from the list instead of changing it - resulting in an error in the next loop cycle.

I probably made some silly mistake and I apologize for bothering you. Any help with this would be appreciated. Thanks  :)

Richard Moss

  • Cyotek Team
  • Administrator
  • Full Member
  • *****
  • Posts: 237
  • Karma: +16/-0
    • cyotek.com
Re: Restrict zoom-out to "Fit"?
« Reply #4 on: September 12, 2017, 05:14:58 PM »
I tested this on the General form of the main demo and it seems to do what you want

Code: [Select]
ZoomLevelCollection levels;
int minimumZoom;

imageBox.ZoomToFit(); // HACK: no current way to get minimum zoom
minimumZoom = imageBox.Zoom;
imageBox.ActualSize();

levels = imageBox.ZoomLevels;

for (int i = levels.Count; i >0; i--)
{
  if (levels[i-1] < minimumZoom)
  {
    levels.RemoveAt(i-1);
  }
}

levels.Add(minimumZoom); // oops, forgot to implement Insert, but at least the list auto sorts

Hope that helps!

Regards;
Richard Moss

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Re: Restrict zoom-out to "Fit"?
« Reply #5 on: September 12, 2017, 06:21:26 PM »
Thanks, I'll try. I'm sure it will work - but unfortunately it will not do exactly what I need. I need the lowest list element to be equal to minimumZoom, while your solution only removes all entries that are smaller than that. So after applying the code the lowest element will be larger than minimumZoom and the image will not completely zoom out.

That's why I tried to replace the first elements by the value of minimumZoom. I still have no idea why it didn't work. For some reason

imgMap.ZoomLevels[level] = imgMap.Zoom;

just removed that list element, instead of replacing it.

Richard Moss

  • Cyotek Team
  • Administrator
  • Full Member
  • *****
  • Posts: 237
  • Karma: +16/-0
    • cyotek.com
Re: Restrict zoom-out to "Fit"?
« Reply #6 on: September 12, 2017, 07:24:30 PM »
Not sure if you noticed, but I do add the minimum - it's right at the end (the code box scrolls).

As I said, I tested this and it seems to do exactly what you wanted - let me know if that's not the case.

Edit: Haven't tried doing the assignments, maybe there's a bug - I'll look into that.

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Re: Restrict zoom-out to "Fit"?
« Reply #7 on: September 12, 2017, 07:34:31 PM »
Sorry, my fault! I didn't scroll down!  :-[

Thanks again!

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Re: Restrict zoom-out to "Fit"?
« Reply #8 on: September 13, 2017, 09:02:25 AM »
I added your code now, and it works fine ... for the initial image.

However, when I load a new image into the imageBox (by assigning a new value to the Image property) it looks like the ZoomLevels collection is not reset. Debugging shows that the list still contains the same values, including the minimumZoom value as item 0.

The line

levels.Add(minimumZoom);

then produces an error, of course, because the value to be added is already present (in case the new image has the same size).

Is there a clever way to reset the imageBox entirely before assigning a new image to it? Or force the ZoomLevels list to be re-calculated?
« Last Edit: September 13, 2017, 02:13:15 PM by ruland »

Richard Moss

  • Cyotek Team
  • Administrator
  • Full Member
  • *****
  • Posts: 237
  • Karma: +16/-0
    • cyotek.com
Re: Restrict zoom-out to "Fit"?
« Reply #9 on: September 13, 2017, 04:33:37 PM »
Normally it doesn't make sense to have custom zoom levels on a per-image basis, so no there's no neat trick. However, it's not too much trouble to do, just replace the for loop (and that floating Add) in my previous example with this

Code: [Select]
levels.Clear();

levels.Add(minimumZoom);

foreach (int level in ZoomLevelCollection.Default)
{
  if (level > minimumZoom)
  {
    levels.Add(level);
  }
}


I tested this and it also looks to be working perfectly.

Regards;
Richard Moss

ruland

  • Newbie
  • *
  • Posts: 15
  • Karma: +0/-0
Re: Restrict zoom-out to "Fit"?
« Reply #10 on: September 13, 2017, 06:48:36 PM »
Perfect! (I wasn't aware that there is a ZoomLevelCollection.Default :) )

Thank you very much for your excellent support and assistance!