如何实现对PictureBox中的图象进行放大和缩小
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现对PictureBox中的图象进行放大和缩小相关的知识,希望对你有一定的参考价值。
图像没跟着变只有一个原因,SizeMode不为Zoom。
微软有提供现成的方法满足你的需要。你唯一需要知道的是一个Control的Position是相对于其父容器的边缘而言的,它叫ClientPoint坐标,并非屏幕坐标ScreenPoint。
下面是一个小方法,用来将任意Control的位置置于屏幕正中间。
int screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
int screenHeight = Screen.PrimaryScreen.WorkingArea.Height;
int targetLocationLeft;
int targetLocationTop;
targetLocationLeft = (screenWidth - control.Width) / 2;
targetLocationTop = (screenHeight - control.Height) / 2;
if (control.Parent != null)
control.Location = control.Parent.PointToClient(new Point(targetLocationLeft, targetLocationTop));
else
control.Location = new Point(targetLocationLeft, targetLocationTop);
关于缩放的问题。所有的Control都有Scale方法,接受一个SizeF作为比例因子。
所以你的picturebox事件里应该这样写(每次放大到1.1倍):
pictureBox1.SuspendLayout();pictureBox1.Scale(new SizeF Width = 1.1f, Height = 1.1f );
SetCenterScreen(pictureBox1);
pictureBox1.ResumeLayout();
其中,SuspendLayout()是挂起布局引擎,这样会暂时阻止它进行外观和布局上的变更(但是会在自己的Graphics上偷偷画好),直到调用ResumeLayout()时才会一次性的迅速的显示出来。
此外,SizeMode只需要被设置一次,没有必要每次都赋值。
最后补一句,Zoom是“按比例缩放图片”,Strech才是“填满容器”,当然,如果picturebox大小比例和图像宽高比不一致,strech会让图片变形。
参考技术A Pegasus的ImagXpress 8.0控件,支持各种格式文件的加载。控件封装了右键局部区域放大的功能,要实现图片的缩放,把AutoResize属性设置为PegasusImaging.WinForms.ImagXpress8.AutoResizeType.CropImage,修改ZoomFactor的值就可以了。
以下是简单的图片缩放
Public Class Form1
Dim MapWidth As Integer
Dim MapHeight As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'设置窗体自动添加滚动条
Me.AutoScroll = True
'设置图片框内的图片自动拉伸
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
'加载位图
Dim MapImage As New Bitmap(Application.StartupPath & "\ch4.png", True)
'图片框加载图片
PictureBox1.Image = MapImage
'设置图片框大小
PictureBox1.Size = New Size(MapImage.Width, MapImage.Height)
'记录原始大小
MapWidth = MapImage.Width
MapHeight = MapImage.Height
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
PictureBox1.Width = PictureBox1.Width * 2
PictureBox1.Height = PictureBox1.Height * 2
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
PictureBox1.Width = PictureBox1.Width / 2
PictureBox1.Height = PictureBox1.Height / 2
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
PictureBox1.Width = MapWidth
PictureBox1.Height = MapHeight
End Sub
End Class
在放大和缩小时在imageview上移动对象
在imageview上有一个可拖动的对象,它已在android中设置为背景。当背景图像视图缩放时,我希望对象保持与之前相同的位置。例如,如果它位于该图像中的“微笑”文本之上,那么即使在缩放后它也应该保持在那里。
我希望图像像谷歌地图一样工作,当我们将标记添加到地图标记根据放大和缩小移动时。
使用下面的Framlayout类,它将缩放其中的所有内容。
public class ZoomableLayout extends FrameLayout {
public ZoomableLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public ZoomableLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public ZoomableLayout(final Context context) {
super(context);
}
/**
* Zooming view listener interface.
*
* @author karooolek
*
*/
public interface ZoomViewListener {
void onZoomStarted(float zoom, float zoomx, float zoomy);
void onZooming(float zoom, float zoomx, float zoomy);
void onZoomEnded(float zoom, float zoomx, float zoomy);
}
// zooming
float zoom = 1.0f;
float maxZoom = 2.0f;
float smoothZoom = 1.0f;
float zoomX, zoomY;
float smoothZoomX, smoothZoomY;
private boolean scrolling; //
// minimap variables
private boolean showMinimap = false;
private int miniMapColor = Color.WHITE;
private int miniMapHeight = -1;
private String miniMapCaption;
private float miniMapCaptionSize = 10.0f;
private int miniMapCaptionColor = Color.WHITE;
// touching variables
private long lastTapTime;
private float touchStartX, touchStartY;
private float touchLastX, touchLastY;
private float startd;
private boolean pinching;
private float lastd;
private float lastdx1, lastdy1;
private float lastdx2, lastdy2;
// drawing
private final Matrix m = new Matrix();
private final Paint p = new Paint();
// listener
ZoomViewListener listener;
private Bitmap ch;
public float getZoom() {
return zoom;
}
public float getMaxZoom() {
return maxZoom;
}
public void setMaxZoom(final float maxZoom) {
if (maxZoom < 1.0f) {
return;
}
this.maxZoom = maxZoom;
}
public void setMiniMapEnabled(final boolean showMiniMap) {
this.showMinimap = showMiniMap;
}
public boolean isMiniMapEnabled() {
return showMinimap;
}
public void setMiniMapHeight(final int miniMapHeight) {
if (miniMapHeight < 0) {
return;
}
this.miniMapHeight = miniMapHeight;
}
public int getMiniMapHeight() {
return miniMapHeight;
}
public void setMiniMapColor(final int color) {
miniMapColor = color;
}
public int getMiniMapColor() {
return miniMapColor;
}
public String getMiniMapCaption() {
return miniMapCaption;
}
public void setMiniMapCaption(final String miniMapCaption) {
this.miniMapCaption = miniMapCaption;
}
public float getMiniMapCaptionSize() {
return miniMapCaptionSize;
}
public void setMiniMapCaptionSize(final float size) {
miniMapCaptionSize = size;
}
public int getMiniMapCaptionColor() {
return miniMapCaptionColor;
}
public void setMiniMapCaptionColor(final int color) {
miniMapCaptionColor = color;
}
public void zoomTo(final float zoom, final float x, final float y) {
this.zoom = Math.min(zoom, maxZoom);
zoomX = x;
zoomY = y;
smoothZoomTo(this.zoom, x, y);
}
public void smoothZoomTo(final float zoom, final float x, final float y) {
smoothZoom = clamp(1.0f, zoom, maxZoom);
smoothZoomX = x;
smoothZoomY = y;
if (listener != null) {
listener.onZoomStarted(smoothZoom, x, y);
}
}
public ZoomViewListener getListener() {
return listener;
}
public void setListner(final ZoomViewListener listener) {
this.listener = listener;
}
public float getZoomFocusX() {
return zoomX * zoom;
}
public float getZoomFocusY() {
return zoomY * zoom;
}
@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
// single touch
if (ev.getPointerCount() == 1) {
processSingleTouchEvent(ev);
}
// // double touch
if (ev.getPointerCount() == 2) {
processDoubleTouchEvent(ev);
}
// redraw
getRootView().invalidate();
invalidate();
return true;
}
private void processSingleTouchEvent(final MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
final float w = miniMapHeight * (float) getWidth() / getHeight();
final float h = miniMapHeight;
final boolean touchingMiniMap = x >= 10.0f && x <= 10.0f + w
&& y >= 10.0f && y <= 10.0f + h;
if (showMinimap && smoothZoom > 1.0f && touchingMiniMap) {
processSingleTouchOnMinimap(ev);
} else {
processSingleTouchOutsideMinimap(ev);
}
}
private void processSingleTouchOnMinimap(final MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
final float w = miniMapHeight * (float) getWidth() / getHeight();
final float h = miniMapHeight;
final float zx = (x - 10.0f) / w * getWidth();
final float zy = (y - 10.0f) / h * getHeight();
smoothZoomTo(smoothZoom, zx, zy);
}
private void processSingleTouchOutsideMinimap(final MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
float lx = x - touchStartX;
float ly = y - touchStartY;
final float l = (float) Math.hypot(lx, ly);
float dx = x - touchLastX;
float dy = y - touchLastY;
touchLastX = x;
touchLastY = y;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStartX = x;
touchStartY = y;
touchLastX = x;
touchLastY = y;
dx = 0;
dy = 0;
lx = 0;
ly = 0;
scrolling = false;
break;
case MotionEvent.ACTION_MOVE:
if (scrolling || (smoothZoom > 1.0f && l > 30.0f)) {
if (!scrolling) {
scrolling = true;
ev.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(ev);
}
smoothZoomX -= dx / zoom;
smoothZoomY -= dy / zoom;
return;
}
break;
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_UP:
// tap
if (l < 30.0f) {
// check double tap
if (System.currentTimeMillis() - lastTapTime < 500) {
if (smoothZoom == 1.0f) {
smoothZoomTo(maxZoom, x, y);
} else {
smoothZoomTo(1.0f, getWidth() / 2.0f,
getHeight() / 2.0f);
}
lastTapTime = 0;
ev.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(ev);
return;
}
lastTapTime = System.currentTimeMillis();
performClick();
}
break;
default:
break;
}
ev.setLocation(zoomX + (x - 0.5f * getWidth()) / zoom, zoomY
+ (y - 0.5f * getHeight()) / zoom);
ev.getX();
ev.getY();
super.dispatchTouchEvent(ev);
}
private void processDoubleTouchEvent(final MotionEvent ev) {
final float x1 = ev.getX(0);
以上是关于如何实现对PictureBox中的图象进行放大和缩小的主要内容,如果未能解决你的问题,请参考以下文章
winform 如何实现鼠标位置获取picturebox的焦点,然后焦点放大
使Print方法在Form_Load事件中起作用,如何对窗体的属性进行设置?
react-native-maps :如何在放大和缩小时获取动态 latitudeDelta 和 longitudeDelta 值