如何在WPF VB中裁剪图像 [英] HOW to crop image in WPF VB
问题描述
我不能在图像控制上裁剪图像请帮忙。
当我将画布x,y,裁剪高度和宽度转移到裁剪功能时它给出错误的小作物图片
提前致谢。
什么我试过了:
Public Function Crop(ByVal srcBitmap As Bitmap,_
ByVal cropX As Integer,ByVal cropY As Integer,ByVal cropWidth As Integer,ByVal cropHeight As Integer)As Bitmap
'创建新的位图和关联的图形对象
Dim bmp As New Bitmap(srcBitmap,cropHeight,cropWidth)
Dim g As Graphics = Graphics.FromImage(bmp)
Dim rect As Rectangle = New Rectangle(cropX,cropY,cropWidth,cropHeight)
'绘制指定的源位图的一部分到新的
g.DrawImage(srcBitmap,New Rectangle(0,0,cropHeight,cropWidth),rect,GraphicsUnit.Pixel)
'清理
srcBitmap.Dispose()
返回bmp
结束函数
Microsoft WPF文档为您提供了一个很好的示例:如何:裁剪图像| Microsoft Docs [ ^ ]
好的,您似乎有计算错误 - 其中一个值可能是 double.NAN [ ^ ]。
此代码具有相同的问题,并且没有被响应的人接收: c# - 使用Canvas矩形裁剪图像 - Stack Overflow [ ^ ]
问题在于这些计算:
rcFrom.X =( int ) ((rect1.X)*(image1.Source.Width)/(image1.Width));
rcFrom.Y =( int )((rect1.Y)*(image1.Source.Height)/(image1.Height));
rcFrom.Width =( int )((rect1.Width)*(image1.Source.Width)/(image1.Width));
rcFrom.Height =( int )((rect1.Height)*(image1.Source.Height)/(image1.Height));
测试&调试显示image1.Height
和image1.Width
正在返回double.NAN
属性。他们应该使用的是image1.ActualHeight
和Actualimage1.Width
属性。
这是代码的更正工作版本(此解决方案中的上述链接)使用图像大小3840 x 2160 jpeg图像:
XAML MainWindow:
< Window
x:Class = WpfCropImage.MainWindow
xmlns = http: //schemas.microsoft.com/winfx/2006/xaml/presentation\"
xmlns:x = http://schemas.microsoft.com/winfx/2006/xaml
mc:可忽略 = d
xmlns:d = http:// schemas。 microsoft.com/expression/blend/2008\"
xmlns:mc = http ://schemas.openxmlformats.org/markup-compatibility/2006
< span class =code-attribute>标题 = CodeProject Answer - WPF Scale&裁剪图像
< span class =code-attribute>高度 = 600 宽度 = 1200 WindowStartupLocation = CenterScreen >
< 网格 >
< Grid.ColumnDefinitions >
< ColumnDefinition / >
< ColumnDefinition 宽度 = 自动 / >
< ColumnDefinition / >
< / Grid.ColumnDefinitions >
< 网格 x:姓名 = Gridimage1 >
< 图像 名称 = image1 < span class =code-attribute> 拉伸 = Uniform
< span class =code-attribute> 来源 = http://eskipaper.com/images/cool-morning-fog-wallpaper-1.jpg / >
< 画布 x:名称 = BackPanel
高度 = {Binding ElementName = image1,Path = ActualHeight}
宽度 ={Binding ElementName = image1,Path = ActualWidth}>
< 矩形 x :名称 = selectionRectangle
描边 = LightBlue 填充 = #220000FF 可见性 = < span class =code-keyword> Collapsed / >
< < span class =code-leadattribute> / Canvas >
< / Grid >
< 按钮 内容 = >> Grid.Column = 1 名称 = 去
点击 = Go_Click FontWeight = 粗体
VerticalAlignment = 中心 保证金 = 10 / >
< 图片 Grid.Column = 2 名称 = image2 拉伸 = 统一 / >
< / Grid >
< / Window >
和MainWindow代码隐藏:
更新8月16日,2017年:新的样本图像显示缩放计算不正确。下面的代码有更正。
使用系统;
使用 System.Windows;
使用 System.Windows.Controls;
使用 System.Windows.Input;
使用 System.Windows.Media.Imaging;
命名空间 WpfCropImage
{
public partial class MainWindow:Window
{
private bool isDragging;
private Point anchorPoint = new Point();
public MainWindow()
{
InitializeComponent();
Gridimage1.MouseLeftButtonDown + = new MouseButtonEventHandler(image1_MouseLeftButtonDown);
Gridimage1.MouseMove + = new MouseEventHandler(image1_MouseMove);
Gridimage1.MouseLeftButtonUp + = new MouseButtonEventHandler(image1_MouseLeftButtonUp);
Go.IsEnabled = false ;
image2.Source = null ;
}
private void Go_Click( object sender,RoutedEventArgs e)
{
if (image1.Source!= null )
{
var rect1 = new Rect()
{
X = Canvas.GetLeft(selectionRectangle),
Y = Canvas.GetTop(selectionRectangle),
Width = selectionRectangle.Width,
高度= selectionRectangle.Height
};
// PIXEls中CroppedBitmap的计算比例...
var img = image1.Source as BitmapSource;
var scaleWidth =(img.PixelWidth)/(image1.ActualWidth);
var scaleHeight =(img.PixelHeight)/(image1.ActualHeight);
var rcFrom = new Int32Rect()
{
X =( int )(rect1.X * scaleWidth),
Y =( int )(rect1.Y * scaleHeight),
Width =( int )(rect1.Width * scaleWidth),
Height =( int )(rect1.Height * scaleHeight)
};
image2.Source = new CroppedBitmap(inputImage,rcFrom);
}
}
#region鼠标事件
private void image1_MouseLeftButtonDown( object sender,MouseButtonEventArgs e)
{
if (!isDragging)
{
anchorPoint.X = e.GetPosition(BackPanel).X;
anchorPoint.Y = e.GetPosition(BackPanel).Y;
isDragging = true ;
}
}
private void image1_MouseMove( object sender,MouseEventArgs e)
{
if (isDragging )
{
double x = e.GetPosition(BackPanel).X;
double y = e.GetPosition(BackPanel).Y;
selectionRectangle.SetValue(Canvas.LeftProperty,Math.Min(x,anchorPoint.X));
selectionRectangle.SetValue(Canvas.TopProperty,Math.Min(y,anchorPoint.Y));
selectionRectangle.Width = Math.Abs(x - anchorPoint.X);
selectionRectangle.Height = Math.Abs(y - anchorPoint.Y);
if (selectionRectangle.Visibility!= Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void image1_MouseLeftButtonUp( object sender,MouseButtonEventArgs e)
{
if (isDragging)
{
isDragging = false ;
if (selectionRectangle.Width > 0 )
{
Go.Visibility = Visibility.Visible;
Go.IsEnabled = true ;
}
if (selectionRectangle.Visibility!= Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void RestRect( )
{
selectionRectangle.Visibility = Visibility.Collapsed;
isDragging = false ;
}
#endregion
}
}
i cant crop image on image control please help.
when i am transfer the canvas x,y,crop height and width to crop function it gives wrong small crop image
Thanks in advance.
What I have tried:
Public Function Crop(ByVal srcBitmap As Bitmap, _ ByVal cropX As Integer, ByVal cropY As Integer, ByVal cropWidth As Integer, ByVal cropHeight As Integer) As Bitmap ' Create the new bitmap and associated graphics object Dim bmp As New Bitmap(srcBitmap, cropHeight, cropWidth) Dim g As Graphics = Graphics.FromImage(bmp) Dim rect As Rectangle = New Rectangle(cropX, cropY, cropWidth, cropHeight) ' Draw the specified section of the source bitmap to the new one g.DrawImage(srcBitmap, New Rectangle(0, 0, cropHeight, cropWidth), rect, GraphicsUnit.Pixel) ' Clean up srcBitmap.Dispose() Return bmp End Function
Microsoft WPF documents has a great example for you: How to: Crop an Image | Microsoft Docs[^]
Okay, it appears that you have a calculation error - one of the values may be double.NAN[^].
This code has the same problem and was not picked up by those that responded: c# - Crop Image using Canvas Rectangle - Stack Overflow[^]
The problem is with these calculations:
rcFrom.X = (int)((rect1.X) * (image1.Source.Width) /(image1.Width)); rcFrom.Y = (int)((rect1.Y) *(image1.Source.Height) / (image1.Height)); rcFrom.Width = (int)((rect1.Width) * (image1.Source.Width) /(image1.Width)); rcFrom.Height = (int)((rect1.Height) * (image1.Source.Height) /(image1.Height));
Testing & debugging has shown thatimage1.Height
andimage1.Width
are returningdouble.NAN
properties. What they should be using isimage1.ActualHeight
andActualimage1.Width
properties.
Here is a corrected working version of the code (above link in this solution) working with an image size of 3840 x 2160 jpeg image:
XAML MainWindow:
<Window x:Class="WpfCropImage.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="CodeProject Answer - WPF Scale & Crop Images" Height="600" Width="1200" WindowStartupLocation="CenterScreen"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="Auto"/> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid x:Name="Gridimage1"> <Image Name="image1" Stretch="Uniform" Source="http://eskipaper.com/images/cool-morning-fog-wallpaper-1.jpg"/> <Canvas x:Name="BackPanel" Height="{Binding ElementName=image1, Path=ActualHeight}" Width="{Binding ElementName=image1, Path=ActualWidth}"> <Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" /> </Canvas> </Grid> <Button Content=">>" Grid.Column="1" Name="Go" Click="Go_Click" FontWeight="Bold" VerticalAlignment="Center" Margin="10"/> <Image Grid.Column="2" Name="image2" Stretch="Uniform" /> </Grid> </Window>
And the MainWindow code-behind:
UPDATE Aug 16, 2017: The new sample image showed that the scaling calculation was incorrect. Below code has the correction.
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media.Imaging; namespace WpfCropImage { public partial class MainWindow : Window { private bool isDragging; private Point anchorPoint = new Point(); public MainWindow() { InitializeComponent(); Gridimage1.MouseLeftButtonDown += new MouseButtonEventHandler(image1_MouseLeftButtonDown); Gridimage1.MouseMove += new MouseEventHandler(image1_MouseMove); Gridimage1.MouseLeftButtonUp += new MouseButtonEventHandler(image1_MouseLeftButtonUp); Go.IsEnabled = false; image2.Source = null; } private void Go_Click(object sender, RoutedEventArgs e) { if (image1.Source != null) { var rect1 = new Rect() { X = Canvas.GetLeft(selectionRectangle), Y = Canvas.GetTop(selectionRectangle), Width = selectionRectangle.Width, Height = selectionRectangle.Height }; // calc scale in PIXEls for CroppedBitmap... var img = image1.Source as BitmapSource; var scaleWidth = (img.PixelWidth) / (image1.ActualWidth); var scaleHeight = (img.PixelHeight) / (image1.ActualHeight); var rcFrom = new Int32Rect() { X = (int)(rect1.X * scaleWidth), Y = (int)(rect1.Y * scaleHeight), Width = (int)(rect1.Width * scaleWidth), Height = (int)(rect1.Height * scaleHeight) }; image2.Source = new CroppedBitmap(inputImage, rcFrom); } } #region "Mouse events" private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (!isDragging) { anchorPoint.X = e.GetPosition(BackPanel).X; anchorPoint.Y = e.GetPosition(BackPanel).Y; isDragging = true; } } private void image1_MouseMove(object sender, MouseEventArgs e) { if (isDragging) { double x = e.GetPosition(BackPanel).X; double y = e.GetPosition(BackPanel).Y; selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X)); selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y)); selectionRectangle.Width = Math.Abs(x - anchorPoint.X); selectionRectangle.Height = Math.Abs(y - anchorPoint.Y); if (selectionRectangle.Visibility != Visibility.Visible) selectionRectangle.Visibility = Visibility.Visible; } } private void image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (isDragging) { isDragging = false; if (selectionRectangle.Width > 0) { Go.Visibility = Visibility.Visible; Go.IsEnabled = true; } if (selectionRectangle.Visibility != Visibility.Visible) selectionRectangle.Visibility = Visibility.Visible; } } private void RestRect() { selectionRectangle.Visibility = Visibility.Collapsed; isDragging = false; } #endregion } }
这篇关于如何在WPF VB中裁剪图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!