You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何将Linq-To-Sql加载的SQL Image转换为WPF ImageBrush.ImageSource

解决Linq-To-Sql加载SQL Image类型转WPF ImageBrush.ImageSource的问题

嘿,我来帮你搞定这个问题!你其实走进了一个小误区——根本不需要把内存里的图像转换成URI,WPF的ImageSource可以直接从字节数组(SQL的Image类型本质就是byte数组)通过流来创建,这才是最直接高效的方式。

步骤1:编写字节数组转BitmapImage的工具方法

WPF里用BitmapImage作为ImageSource的实现类,我们可以写一个方法把从数据库拿到的byte数组转成它:

Imports System.IO
Imports System.Windows.Media.Imaging

Private Function ByteArrayToBitmapImage(ByVal byteArray As Byte()) As BitmapImage
    ' 空数组直接返回null
    If byteArray Is Nothing OrElse byteArray.Length = 0 Then
        Return Nothing
    End If

    Using stream As New MemoryStream(byteArray)
        Dim bitmapImage As New BitmapImage()
        bitmapImage.BeginInit()
        ' 必须设置这个选项!否则流关闭后图像会失效
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad
        bitmapImage.StreamSource = stream
        bitmapImage.EndInit()
        ' 可选:冻结图像提升性能,尤其适合绑定场景
        bitmapImage.Freeze()
        Return bitmapImage
    End Using
End Function

步骤2:调整绑定的数据源属性

你XAML里绑定的Picture属性,类型应该是ImageSource(而不是byte数组或者System.Drawing.Image)。假设你用的是ViewModel模式,修改你的类:

Imports System.ComponentModel
Imports System.Windows.Media

Public Class YourViewModel
    Implements INotifyPropertyChanged

    Private _picture As ImageSource
    Public Property Picture As ImageSource
        Get
            Return _picture
        End Get
        Set(value As ImageSource)
            _picture = value
            ' 触发属性变更通知,让UI更新
            OnPropertyChanged(NameOf(Picture))
        End Set
    End Property

    ' INotifyPropertyChanged接口实现
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    Private Sub OnPropertyChanged(propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

    ' 加载数据时调用这个方法
    Public Sub LoadImageFromDatabase()
        ' 从Linq-To-Sql获取byte数组(SQL的Image类型对应byte[])
        Dim imageBytes As Byte() = listOfImage(...) ' 替换成你的实际数据获取逻辑
        ' 转换后赋值给Picture属性
        Me.Picture = ByteArrayToBitmapImage(imageBytes)
    End Sub
End Class

步骤3:确认XAML和DataContext

你的XAML代码已经写对了,只要确保你的Rectangle所在的控件的DataContext设置为上面的ViewModel实例就行:

<Rectangle Grid.Row="1" RadiusX="3" RadiusY="3" Width="110" Height="80">
    <Rectangle.Fill>
        <ImageBrush x:Name="brush" ImageSource="{Binding Picture}"/>
    </Rectangle.Fill>
</Rectangle>

关键注意点

  • 不要用System.Drawing.Image中转:你代码里提到的System.Drawing.Image是WinForms的类型,WPF完全不需要它,直接处理byte数组更高效,也避免了跨UI框架的转换问题。
  • 必须设置BitmapCacheOption.OnLoad:因为我们用的是Using块包裹MemoryStream,流会在块结束后被释放,如果不设置这个选项,BitmapImage会延迟加载,导致流关闭后图像无法显示。
  • Freeze()的作用:调用这个方法可以让BitmapImage变成只读对象,不仅能提升WPF的渲染性能,还允许在非UI线程创建图像(不过绑定操作还是要在UI线程)。

内容的提问来源于stack exchange,提问作者joebohen

火山引擎 最新活动