Modifier les premières données de pixels de WriteableBitmap?
Est-il possible de passer directement à la lecture/écriture à une WriteableBitmap données de pixel? Je suis actuellement à l'aide WriteableBitmapEx de SetPixel()
mais c'est lent et je veux accéder aux pixels directement sans aucune surcharge.
Je n'ai pas utilisé HTML5 canvas en temps, mais si je me souviens correctement, vous pourriez obtenir ses données d'image comme un tableau unique de chiffres et c'est le genre de ce que je suis à la recherche d'
Merci d'avance
Vous devez vous connecter pour publier un commentaire.
Pour répondre à votre question, vous pouvez directement accéder à un bitmap accessible en écriture de données à l'aide de la
Lock
, écrire,Unlock
motif, tel que démontré ci-dessous, mais il n'est généralement pas nécessaire, sauf si vous basez votre dessin sur le contenu de l'image. Plus généralement, il vous suffit de créer un nouveau tampon et d'en faire une image bitmap, plutôt que l'inverse.Cela étant dit, il ya beaucoup de points d'extensibilité dans WPF pour effectuer innovantes dessin sans avoir recours à la manipulation de pixels. Pour la plupart des contrôles de l'existant WPF primitives (Frontière, une Ligne, un Rectangle, une Image, etc...) sont plus que suffisantes - ne vous préoccupez pas de l'aide de beaucoup d'entre eux, ils sont plutôt bon marché à utiliser. Pour les commandes complexes, vous pouvez utiliser le DrawingContext pour dessiner D3D primitives. Pour les effets d'image, vous pouvez mettre en œuvre des GPU assistée shaders à l'aide de la
Effet
de la classe ou utiliser le construit en effets (Flou et de l'Ombre).Mais, si votre situation l'exige l'accès direct aux pixels, choisissez un format de pixel et de commencer à écrire. Je suggère BGRA32 parce que c'est facile à comprendre et est probablement le plus commun d'être discuté.
BGRA32 signifie que les données de pixel est stocké dans la mémoire de 4 octets représentant le bleu, le vert, le rouge, et les canaux alpha d'une image, dans cet ordre. C'est pratique, car chaque pixel se termine sur une frontière d'octet 4, de le prêter à un stockage dans un entier de 32 bits. Lorsque vous traitez avec un entier de 32 bits, gardez à l'esprit l'ordre sera inversé sur la plupart des plateformes (vérifier
BitConverter.IsLittleEndian
pour déterminer le bon ordre des octets lors de l'exécution si vous avez besoin de prendre en charge plusieurs plates-formes x86 et x86_64 sont à la fois little endian)Les données d'image sont stockées dans des bandes horizontales qui sont un
stride
large qui composent une seule ligne de la largeur d'une image. Lestride
la largeur est toujours supérieure ou égale à la largeur en pixels de l'image multiplié par le nombre d'octets par pixel dans le format sélectionné. Certaines situations peuvent entraîner la foulée à plus long que lewidth * bytesPerPixel
qui sont spécifiques à certains architechtures, de sorte que vous devez utiliser la foulée de la largeur pour calculer le début d'une ligne, plutôt que de multiplier la largeur. Puisque nous sommes à l'aide d'un 4 octets de large format de pixel, notre rythme de croisière arrive à êtrewidth * 4
, mais vous ne devriez pas compter sur elle.Comme mentionné, le seul cas je conseille un WritableBitmap est si vous accédez à une image existante, de sorte que c'est l'exemple ci-dessous:
Avant /Après:
Cependant, il n'est vraiment pas nécessaire si vous n'êtes pas modifier une image existante. Par exemple, vous pouvez dessiner un motif en damier à l'aide de tous les coffre-fort à code:
De sortie:
Et vous n'avez pas vraiment besoin même un Int32 intermédiaire, si vous écrivez au tableau d'octets directement.
De sortie:
Edit: apparemment, vous essayez d'utiliser WPF pour faire une sorte d'image de l'éditeur. Je serais toujours à l'aide de WPF primitives pour des formes et des bitmaps, puis de mettre en œuvre des traductions, mise à l'échelle, rotation, comme
RenderTransform
's, les effets bitmap commeEffect
's et de tout garder dans le modèle WPF. Mais, si cela ne fonctionne pas pour vous, nous avons de nombreuses autres options.Vous pouvez utiliser WPF primitives à rendre à un
RenderTargetBitmap
qui a choisiPixelFormat
à utiliser avecWritableBitmap
comme ci-dessous:Vous pouvez utiliser WPF
DrawingVisual
à la question GDI style de commandes, puis rendu à une image bitmap comme le montre l'exemple sur leRenderTargetBitmap
page.Vous pourriez utiliser l'interface graphique à l'aide d'un
InteropBitmap
créé à l'aide deSystem.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap
à partir d'unHBITMAP
récupérées à partir d'unBitmap.GetHBitmap
méthode. Assurez-vous que vous n'avez pas de fuite de laHBITMAP
, si.BitmapSource
et vous pouvez convertir entre pixelformats à l'aide de laFormatConvertedBitmap
de classe, mais encore une fois, il ne devrait pas être nécessaire. Pouvez-vous expliquer ce que vous essayez de faire? PBGRA est généralement utilisé dans le stockage d'images, pas de création ou d'édition.Rectangle
,Polygon
, etc...,DrawingContext
, ou vous pouvez même utiliser l'interface graphique dans un pincement. Est-il une raison pour laquelle vous êtes à l'aide deWritableBitmapEx
?Après une belle et longue des maux de tête, j'ai trouvé cet article qui explique une façon de le faire sans l'aide de peu d'arithmétique, et me permet de la traiter comme un tableau à la place:
Vous pouvez accéder aux premières données de pixels en appelant le
Lock()
méthode et à l'aide de laBackBuffer
de la propriété par la suite. Lorsque vous avez terminé, n'oubliez pas d'appelerAddDirtyRect
etUnlock
.Pour un exemple simple, vous pouvez prendre un coup d'oeil à ceci: http://cscore.codeplex.com/SourceControl/latest#CSCore.Visualization/WPF/Utils/PixelManipulationBitmap.cs
*((int*)pBackBuffer) = color_data;
à partir de votre lien (avec le code) pour le régler. Mais une question: comment puis-je le lire de la même façon?color_data = *((int*)pBackBuffer)
). Dans un format ARGB, le MSB est titulaire d'un 8 bits de la valeur alpha. Vous pouvez le régler en faisant peu d'arithmétique. E. g.:currentValue & 0x00ffffff | (newAValue << 24)
elle à l'arbitraire d'un octet. Voir MSDN Pour en savoir plus sur le code unsafe msdn.microsoft.com/en-us/library/aa664774(v=vs. 71).aspx.