请教关于图片裁剪时,如何实现自定义裁剪方向的问题

hero2964 2008-05-19 04:02:46
现在需要实现一个手机图片下载的功能,大概需求是后台不分尺寸上传原图(原图尺寸一般情况下均大于手机屏幕大小),前台页面用户输入自己手机屏幕尺寸下载,下载前程序自动等比率缩小并裁剪成用户所需尺寸保存在服务器供用户下载!
目前基本功能已实现,目前的设计是如果等比率缩小后需要裁掉一部分来适合手机屏幕则默认保留左上方部分,裁掉右下部分。但又发现这样裁剪的精度不够,经常出现人物被裁掉一半的情况,急需改进。
现在打算改进如下:后台上传原图时,根据原图画面布局情况,选择裁剪方向(如:裁掉左上,左下,右上,右下),并记录在数据库相应字段中,前台用户输入尺寸下载前,以输入尺寸的宽或高为基准(以较长的为基准)自动等比例缩小,若缩小后不满足手机尺寸,则按数据库中记录的裁剪方向裁剪,以达到人工控制裁剪精度的目的。

问题:如何利用DrawImage()方法来实现自定义方向裁剪?
希望各位高手指教,或提供更为简便可行的方案来提高裁剪的精度,第一次发帖暂无分可给,以后努力打工赚分偿还,小弟先行作揖了! ^_^

下面提供小弟目前默认裁剪右下部分的方法源码,请各位看官多多改进,指教,小弟感激不尽……

Public Sub Dram(ByVal p_img_Original As Image, ByVal p_int_Width As Integer, ByVal p_int_Height As Integer)
Dim l_int_OriWidth As Integer = p_img_Original.Width
Dim l_int_OriHeight As Integer = p_img_Original.Height
Dim l_int_IntWidth As Integer = 0
Dim l_int_IntHeight As Integer = 0
Dim l_int_OffsetX As Integer = 0
Dim l_int_OffsetY As Integer = 0

' 以寬度為基準,保持寬高比計算縮放之後的高度
l_int_IntWidth = p_int_Width
l_int_IntHeight = l_int_OriHeight * l_int_IntWidth / l_int_OriWidth

' 如果縮放之後的高度不夠新高度,則改用以高度為基準,保持寬高比計算縮放之後的寬度
If l_int_IntHeight < p_int_Height Then
l_int_IntHeight = p_int_Height
l_int_IntWidth = l_int_OriWidth * l_int_IntHeight / l_int_OriHeight

' 計算圖片偏移位置
Else
' 計算圖片偏移位置
l_int_OffsetY = (p_int_Height - l_int_IntHeight) / 4 ' 垂直居中偏上
End If

' 準備畫布
Dim l_bmp_New As Bitmap = New Bitmap(p_int_Width, p_int_Height)
Dim l_gph_New As Graphics = Graphics.FromImage(l_bmp_New)
l_gph_New.InterpolationMode = InterpolationMode.High
l_gph_New.SmoothingMode = SmoothingMode.HighQuality
l_gph_New.Clear(Color.Transparent)

' 生成圖片
l_gph_New.DrawImage(p_img_Original, New Rectangle(l_int_OffsetX, l_int_OffsetY, l_int_IntWidth, l_int_IntHeight))

'输出图片
'prepare output stream buffer
Dim l_ms_Buffer As MemoryStream = New MemoryStream()
l_bmp_New.Save(l_ms_Buffer, ImageFormat.Jpeg)
' output to browser
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ContentType = "image/jpeg"
HttpContext.Current.Response.BinaryWrite(l_ms_Buffer.ToArray())
End Sub
...全文
546 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
name_zzxc 2009-04-23
  • 打赏
  • 举报
回复
右没有c#的啊 看这VB人好累~!~!
hero2964 2008-05-25
  • 打赏
  • 举报
回复

Public Sub Dram(ByVal p_img_Original As Image, ByVal p_int_Width As Integer, ByVal p_int_Height As Integer, ByVal p_int_Direction As Integer, ByVal p_str_SavePath As String)
Dim l_int_OriginalWidth As Integer = p_img_Original.Width
Dim l_int_OriginalHight As Integer = p_img_Original.Height
Dim l_int_TargetWidth As Integer = 0
Dim l_int_TargetHight As Integer = 0

If p_int_Width <= p_int_Height Then
l_int_TargetHight = p_int_Height
l_int_TargetWidth = l_int_OriginalWidth * l_int_TargetHight / l_int_OriginalHight
Else
l_int_TargetWidth = p_int_Width
l_int_TargetHight = l_int_OriginalHight * l_int_TargetWidth / l_int_OriginalWidth
End If

Dim l_bmp_TempOut As New Bitmap(l_int_TargetWidth, l_int_TargetHight)
Dim l_grp_TempGraphics As Graphics = Graphics.FromImage(l_bmp_TempOut)
l_grp_TempGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High
l_grp_TempGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
l_grp_TempGraphics.Clear(Color.Transparent)
l_grp_TempGraphics.DrawImage(p_img_Original, New Rectangle(0, 0, l_int_TargetWidth, l_int_TargetHight), New Rectangle(0, 0, l_int_OriginalWidth, l_int_OriginalHight), GraphicsUnit.Pixel)


Dim l_bmp_TargetOut As New Bitmap(p_int_Width, p_int_Height)
Dim l_grp_TargetGraphics As Graphics = Graphics.FromImage(l_bmp_TargetOut)
l_grp_TargetGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High
l_grp_TargetGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
l_grp_TargetGraphics.Clear(Color.Transparent)

Dim obj As Object = l_bmp_TempOut
Dim l_img_TragImage As System.Drawing.Image = CType(l_bmp_TempOut, System.Drawing.Image)

Dim l_int_x As Integer = 0
Dim l_int_y As Integer = 0

If p_int_Direction = 0 Then
l_int_x = (l_int_TargetWidth - p_int_Width) / 2
l_int_y = (l_int_TargetHight - p_int_Height) / 2
ElseIf p_int_Direction = 1 Then '左上
l_int_x = 0
l_int_y = 0
ElseIf p_int_Direction = 2 Then '左下
l_int_x = 0
l_int_y = l_int_TargetHight - p_int_Height
ElseIf p_int_Direction = 3 Then '右上
l_int_x = l_int_TargetWidth - p_int_Width
l_int_y = 0
ElseIf p_int_Direction = 4 Then '右下
l_int_x = l_int_TargetWidth - p_int_Width
l_int_y = l_int_TargetHight - p_int_Height
End If


l_grp_TargetGraphics.DrawImage(l_img_TragImage, New Rectangle(0, 0, p_int_Width, p_int_Height), New Rectangle(l_int_x, l_int_y, p_int_Width, p_int_Height), GraphicsUnit.Pixel)

'保存图片
Dim DirectoryStr As String = p_str_SavePath.Substring(0, p_str_SavePath.LastIndexOf("\") + 1)
If Not Directory.Exists(DirectoryStr) Then
Directory.CreateDirectory(DirectoryStr)
End If

l_bmp_TargetOut.Save(p_str_SavePath)
l_bmp_TempOut.Dispose()
l_bmp_TargetOut.Dispose()
l_grp_TempGraphics.Dispose()
l_grp_TargetGraphics.Dispose()
p_img_Original.Dispose()

''输出图片
''prepare output stream buffer
'Dim l_ms_Buffer As MemoryStream = New MemoryStream()
'l_bmp_TargetOut.Save(l_ms_Buffer, ImageFormat.Jpeg)
''output to browser
'HttpContext.Current.Response.Clear()
'Image1.ImageUrl = Server.MapPath("~") + "\TestImage\test.jpg"
'HttpContext.Current.Response.ContentType = "image/jpeg"
'HttpContext.Current.Response.BinaryWrite(l_ms_Buffer.ToArray())
End Sub


暂时用以上代码实现交差了 结贴……
hero2964 2008-05-23
  • 打赏
  • 举报
回复
感谢 炎龙无悔

用你提供的程序测试了一下,图片没有被裁掉的情况,但当原图长宽比与尺寸长宽比差距较大时存在图片变形的情况
仍不是很精确,再次表示感谢,明日此时结贴,^_^!
yanlongwuhui 2008-05-21
  • 打赏
  • 举报
回复
提供参考,你自己修改下:
Dim iNewWidth As Integer
Dim iNewHeight As Integer
Dim units As GraphicsUnit = GraphicsUnit.Pixel
Try
Dim sourceImg As Image = Image.FromFile("图片路径")
Dim b As New Bitmap(iNewWidth, iNewHeight, PixelFormat.Format32bppArgb)
Dim g As Graphics = Graphics.FromImage(b)
Dim p1(2) As Point
g.Clear(Color.Transparent)
p1(0) = New Point(0, 0)
p1(1) = New Point(iNewWidth, 0)
p1(2) = New Point(0, iNewHeight)
g.DrawImage(sourceImg, p1, New Rectangle(0, 0, sourceImg.Width, sourceImg.Height), units)
Dim fi As System.IO.FileInfo = New System.IO.FileInfo("保存的路径")
If fi.Directory.Exists = False Then
fi.Directory.Create()
End If
b.Save("保存的路径")
sourceImg.Dispose()
Catch ex As Exception
End Try
hero2964 2008-05-20
  • 打赏
  • 举报
回复
首先对炎龙无悔提出的建议表示感谢!

由于用户下载图片是作为手机屏保来用的,如果左右或上下出现空白会影响屏保效果
yanlongwuhui 2008-05-20
  • 打赏
  • 举报
回复
为什么不考虑采用图片符合指定大小且保持屏幕高宽比的方式?就是保持图片能完整显示,宽度(高度)不够时不够的是显示空白的,而不是裁剪。

16,717

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧