Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Работа с битами изображения Добавлено: 15.10.08 21:36  

Автор вопроса:  Oleg
Народ, помогите пожалуйста. Имеется такая ситуация.
Необходимо перевести свой старый проект с Borland C++ на Microsoft C++ managed, с использованием VCL, разумеется. В проекте у меня содержится графичекая часть, т.е. функции работы с изображением через метод ScanLine.
Это метод позволяет получить указатель на пиксели изображения и работать с ним как с обычным набором байт, т.е. как с массивом.
Методы SetPixel и GetPixel черезвычайно тормознутые и нужно работать с зображинием, именно как с массивом.

Имеется-ли что-то подобное в NET? Как можно это реализовать на NET?

Ответить

  Ответы Всего ответов: 4  

Номер ответа: 1
Автор ответа:
 Фeнягz



Вопросов: 2
Ответов: 62
 Web-сайт: atauenis.narod.ru
 Профиль | | #1
Добавлено: 16.10.08 02:50
:D

Пример использования:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   Dim bmp As New Bitmap("c:\1.bmp";)
   Dim p As New Pixxxelz(bmp) : bmp.Dispose()
   For x As Integer = 0 To p.Width - 1
       For y As Integer = 0 To p.Height - 1
           Dim pix As Pixxxelz.ARGB = p.GetPixel(x, y)
           Dim gray As Byte = (0.299 * pix.r) + (0.587 * pix.g) + (0.114 * pix.b)
           Call p.SetPixel(x, y, New Pixxxelz.ARGB(255, gray, gray, gray))
       Next
   Next
   Me.WindowState = FormWindowState.Maximized
   Me.BackgroundImage = p.ToBitmap(True)
   p.Dispose()
   MsgBox("GRAYSCALE";)
End Sub


Класс:

Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices

' Работаем с пикселами 32-битового изображения (Format32bppArgb)

Public Class Pixxxelz

' na http://sontse.hmarka.net/ abo http://igorr.zx6.ru/ ye pizdata demo programa i kucha raznogo ohuyennogo koda!

Implements ICloneable
Implements IDisposable

Public Declare Ansi Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" _
       ;(ByVal Dst As IntPtr, ByVal Src As IntPtr, ByVal Length As Integer)
Public Declare Ansi Sub memcpy2 Lib "kernel32" Alias "RtlMoveMemory" _
       ;(ByVal Dst As Byte, ByVal Src As IntPtr, ByVal Length As Integer)
Public Declare Ansi Sub memcpy3 Lib "kernel32" Alias "RtlMoveMemory" _
       ;(ByVal Dst As ARGB, ByVal Src As IntPtr, ByVal Length As Integer)

#Region " ARGB - структура работы с 32-битовым цветом (Drawing.Color - не годится)"

Public Structure ARGB

Dim b As Byte
Dim g As Byte
Dim r As Byte
Dim a As Byte

' Параметризированный конструктор

Public Sub New(ByVal a As Byte, ByVal r As Byte, ByVal g As Byte, ByVal b As Byte)
   Me.a = a : Me.r = r : Me.g = g : Me.b = b
End Sub

End Structure

#End Region

Friend _width As Integer
Friend _height As Integer
Friend _ptr As IntPtr
Friend _length As Integer

Public Sub New(ByVal img As Bitmap)
   MyBase.New()
   Dim tmp As New Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb)
   Dim g As Graphics = Graphics.FromImage(tmp)
   Call g.DrawImageUnscaled(img, 0, 0) : g.Dispose()
   _length = img.Width * img.Height * 4 ' Длина данных 32-битового изображения в памяти (4 байта на пиксел)
   _ptr = Marshal.AllocHGlobal(_length) ' Выделяем отдельно память
   ' Блокируем данные изображения
   Dim data As BitmapData = tmp.LockBits(New Rectangle(0, 0, tmp.Width, _
   tmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)
   Call memcpy(_ptr, data.Scan0, _length)
   Call tmp.UnlockBits(data) : tmp.Dispose()
   _width = img.Width : _height = img.Height
End Sub

Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal value As ARGB)
   Dim ofs As Integer = ((y * Width) + x) * 4
   Marshal.WriteByte(_ptr, ofs + 3, value.a)
   Marshal.WriteByte(_ptr, ofs + 2, value.r)
   Marshal.WriteByte(_ptr, ofs + 1, value.g)
   Marshal.WriteByte(_ptr, ofs, value.b)
End Sub

Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As ARGB
   Dim ofs As Integer = ((y * Width) + x) * 4
   Return New ARGB(Marshal.ReadByte(_ptr, ofs + 3), Marshal.ReadByte(_ptr, ofs + 2), _
   Marshal.ReadByte(_ptr, ofs + 1), Marshal.ReadByte(_ptr, ofs))
End Function

' Получить изображение
' (copy = false) - изображение на основе графической информации данного объекта
' (copy = true) - изображение на основе копии графической информации данного объекта
Public Function ToBitmap(Optional ByVal copy As Boolean = False) As Bitmap
   If copy Then
      Dim p As Pixxxelz = CType(Clone(), Pixxxelz)
      Return p.ToBitmap(False)
   Else
      Return New Bitmap(Width, Height, Width * 4, PixelFormat, Pointer)
   End If
End Function

Public ReadOnly Property Width() As Integer
 Get
    Return _width
 End Get
End Property

Public ReadOnly Property Height() As Integer
 Get
    Return _height
 End Get
End Property

Public ReadOnly Property Length() As Integer
 Get
    Return _length
 End Get
End Property

Public ReadOnly Property Pointer() As IntPtr
 Get
    Return _ptr
 End Get
End Property

Public ReadOnly Property PixelFormat() As PixelFormat
 Get
    Return Imaging.PixelFormat.Format32bppArgb
 End Get
End Property

#Region " для общего развития"

Public Shared Operator =(ByVal first As Pixxxelz, ByVal second As Pixxxelz) As Boolean
   Return first._ptr.ToInt32 = second._ptr.ToInt32
End Operator

Public Shared Operator <>;(ByVal first As Pixxxelz, ByVal second As Pixxxelz) As Boolean
   Return Not first = second
End Operator

Public Function Clone() As Object Implements System.ICloneable.Clone
   Dim pxlz As New Pixxxelz
   With pxlz
      ._ptr = Marshal.AllocHGlobal(_length)
      Call memcpy(._ptr, _ptr, _length)
      ._height = _height
      ._width = _width
      ._length = _length
   End With
   Return pxlz
End Function

Public Sub Dispose() Implements IDisposable.Dispose
   On Error GoTo nahuy
   Call Marshal.FreeHGlobal(_ptr)
   Finalize()
   Return
nahuy:
End Sub

Friend Sub New()
   MyBase.New()
End Sub

#End Region

Public Function ToByteArray() As Byte()
   Dim arr((Width * Height * 4) - 1) As Byte
   Call memcpy2(arr(0), Pointer, Length)
   Return arr
End Function

Public Function ToArgb() As ARGB()
   Dim arr((Width * Height) - 1) As ARGB
   Call memcpy3(arr(0), Pointer, Length)
   Return arr
End Function

End Class

Ответить

Номер ответа: 2
Автор ответа:
 Фeнягz



Вопросов: 2
Ответов: 62
 Web-сайт: atauenis.narod.ru
 Профиль | | #2
Добавлено: 16.10.08 03:28
БАГГИ

Public Declare Ansi Sub memcpy2 Lib "kernel32" Alias "RtlMoveMemory" _
       ;(ByVal Dst() As Byte, ByVal Src As IntPtr, ByVal Length As Integer)
Public Declare Ansi Sub memcpy3 Lib "kernel32" Alias "RtlMoveMemory" _
       ;(ByVal Dst() As ARGB, ByVal Src As IntPtr, ByVal Length As Integer)

' и это

Public Function ToByteArray() As Byte()
   Dim arr((Width * Height * 4) - 1) As Byte
   Call memcpy2(arr, Pointer, Length)
   Return arr
End Function

Public Function ToArgb() As ARGB()
   Dim arr((Width * Height) - 1) As ARGB
   Call memcpy3(arr, Pointer, Length)
   Return arr
End Function

Ответить

Номер ответа: 3
Автор ответа:
 Skywalker



ICQ: 300-70-6пятьЪ 

Вопросов: 62
Ответов: 545
 Web-сайт: iSkywalker.ru
 Профиль | | #3
Добавлено: 16.10.08 08:04
  1.  
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5.  
  6.  
  7. namespace Image
  8. {
  9.     public unsafe class FastBitmap
  10.     {
  11.         public struct PixelData
  12.         {
  13.             public byte blue;
  14.             public byte green;
  15.             public byte red;
  16.         }
  17.         Bitmap Subject;
  18.         int SubjectWidth;
  19.         BitmapData bitmapData = null;
  20.         Byte* pBase = null;
  21.         public FastBitmap(Bitmap SubjectBitmap)
  22.         {
  23.             this.Subject = SubjectBitmap;
  24.             try
  25.             {
  26.                 LockBitmap();
  27.             }
  28.             catch (Exception ex)
  29.             {
  30.                 throw ex;
  31.             }
  32.         }
  33.         public void Release()
  34.         {
  35.             try
  36.             {
  37.                 UnlockBitmap();
  38.             }
  39.             catch (Exception ex)
  40.             {
  41.                 throw ex;
  42.             }
  43.         }
  44.         public Bitmap Bitmap
  45.         {
  46.             get
  47.             {
  48.                 return Subject;
  49.             }
  50.         }
  51.         public void SetPixel(int X, int Y, Color Colour)
  52.         {
  53.             try
  54.             {
  55.                 PixelData* p = PixelAt(X, Y);
  56.                 p->red = Colour.R;
  57.                 p->green = Colour.G;
  58.                 p->blue = Colour.B;
  59.             }
  60.             catch (AccessViolationException ave)
  61.             {
  62.                 throw ave;
  63.             }
  64.             catch (Exception ex)
  65.             {
  66.                 throw ex;
  67.             }
  68.         }
  69.         public Color GetPixel(int X, int Y)
  70.         {
  71.             try
  72.             {
  73.                 PixelData* p = PixelAt(X, Y);
  74.                 return Color.FromArgb((int)p->red, (int)p->green, (int)p->blue);
  75.             }
  76.             catch (AccessViolationException ave)
  77.             {
  78.                 throw ave;
  79.             }
  80.             catch (Exception ex)
  81.             {
  82.                 throw ex;
  83.             }
  84.         }
  85.         private void LockBitmap()
  86.         {
  87.             GraphicsUnit unit = GraphicsUnit.Pixel;
  88.             RectangleF boundsF = Subject.GetBounds(ref unit);
  89.             Rectangle bounds = new Rectangle((int)boundsF.X,(int)boundsF.Y,(int)boundsF.Width,(int)boundsF.Height);
  90.             SubjectWidth = (int)boundsF.Width * sizeof(PixelData);
  91.             if (SubjectWidth % 4 != 0)
  92.             {
  93.                 SubjectWidth = 4*(SubjectWidth / 4 +1);
  94.             }
  95.             bitmapData = Subject.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  96.             pBase = (Byte*)bitmapData.Scan0.ToPointer();
  97.         }
  98.         private PixelData* PixelAt(int x, int y)
  99.         {
  100.             return (PixelData*)(pBase + y * SubjectWidth + x * sizeof(PixelData));
  101.         }
  102.         private void UnlockBitmap()
  103.         {
  104.             Subject.UnlockBits(bitmapData);
  105.             bitmapData = null;
  106.             pBase = null;
  107.         }
  108.     }
  109. }

Ответить

Номер ответа: 4
Автор ответа:
 Oleg



Вопросов: 9
Ответов: 16
 Профиль | | #4 Добавлено: 16.10.08 23:16
Всем большое спасибо!

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам