Bonjour à tous,
J'ai créé un programme qui traite des images
J'ai trouvé ce code qui permet de lire efficacement la couleur des pixels (fonction GetPixel rapide) sans recourir à du code unsafe:
https://stackoverflow.com/questions/...-for-windows-f
Ce code marche mais il créé un bitmap "vierge"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class DirectBitmap : IDisposable { public Bitmap Bitmap { get; private set; } public Int32[] Bits { get; private set; } public bool Disposed { get; private set; } public int Height { get; private set; } public int Width { get; private set; } protected GCHandle BitsHandle { get; private set; } public DirectBitmap(int width, int height) { Width = width; Height = height; Bits = new Int32[width * height]; BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned); Bitmap = new Bitmap(width, height, width * 4, PixelFormat.Format32bppPArgb, BitsHandle.AddrOfPinnedObject()); } public void SetPixel(int x, int y, Color colour) { int index = x + (y * Width); int col = colour.ToArgb(); Bits[index] = col; } public Color GetPixel(int x, int y) { int index = x + (y * Width); int col = Bits[index]; Color result = Color.FromArgb(col); return result; } public void Dispose() { if (Disposed) return; Disposed = true; Bitmap.Dispose(); BitsHandle.Free(); } }
Je ne sais pas comment faire pour créer un nouveau bitmap à partir d'une image existante.
Je l'ai adapté en VB.NET (mon logiciel a son interface et le gros du code en VB.NET, avec quelques DLL écrites en C# que j'ai modifié)
J'ai ajouté un deuxième constructeur permettant de créer le DirectBitmap à partir d'un fichier et c'est là que je ne sais pas comment faire.
Code VBNET : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Public Class DirectBitmap 'Inherits IDisposable Public Property Bitmap As Bitmap Public Property Bits As Int32() Public Property Disposed As Boolean Public Property Height As Integer Public Property Width As Integer Protected Property BitsHandle As GCHandle Public Sub New(File As String) 'Lecture du fichier (qui peut être une image de n'importe quel type) Dim bm As Bitmap bm = CType(Image.FromFile(File), Bitmap) Width = bm.Width Height = bm.Height Bits = New Int32(Width * Height - 1) {} BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned) Bitmap = New Bitmap(Width, Height, Width * 4, PixelFormat.Format32bppPArgb, BitsHandle.AddrOfPinnedObject()) 'Comment faire pour "peindre" le contenu de 'bm' dans 'Bitmap' ??? bm.Dispose() End Sub Public Sub New(ByVal width As Integer, ByVal height As Integer) width = width height = height Bits = New Int32(width * height - 1) {} BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned) Bitmap = New Bitmap(width, height, width * 4, PixelFormat.Format32bppPArgb, BitsHandle.AddrOfPinnedObject()) End Sub Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal colour As Color) Dim index As Integer = x + (y * Width) Dim col As Integer = colour.ToArgb() Bits(index) = col End Sub Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As Color Dim index As Integer = x + (y * Width) Dim col As Integer = Bits(index) Dim result As Color = Color.FromArgb(col) Return result End Function Public Sub Dispose() If Disposed Then Return Disposed = True Bitmap.Dispose() BitsHandle.Free() End Sub End Class
Le constructeur new Bitmap() permet de nombreuses possibilités avec différents paramètres, mais aucun ne permet d'avoir à la fois comme paramètres:
- PixelFormat.Format32bppPArgb et BitsHandle.AddrOfPinnedObject
- File
Je précise qu'il faut que ce soit rapide... car faire des bm.GetPixel() classiques (donc lents) pour remplir DirectBitmap.Bitmap n'a aucun intérêt
Il y a probablement une façon toute bête d'y parvenir mais je ne vois pas
Peut-être peut-on le faire via un objet "Graphics", en effet on peut faire ça avec cette classe DirectBitmap :
A bientôt
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 var dbm = new DirectBitmap(200, 200); using (var g = Graphics.FromImage(dbm.Bitmap)) { g.DrawRectangle(Pens.Black, new Rectangle(50, 50, 100, 100)); }
Partager