J'ai une gamme 3D d'octets en C # que j'ai lu depuis un bitmap: Quelle est la manière la plus facile et la plus performante de remodeler ce tableau en 2D (linéaire) forme? p> En d'autres termes, je veux conserver le nombre de canaux (fonctionnalités) mais dans une forme linéaire (plutôt qu'une forme carrée) p> let Moi essaye d'illustrer l'entrée et la sortie souhaitée: p> entrée: p> |(r1,g1,b1) (r2,g2,b2) (r3,g3,b3) (r4,g4,b4) (r5,g5,b5) (r6,g6,b6) ...|
3 Réponses :
Cela semble fonctionner bien, car le tableau est déjà dans la bonne forme en mémoire em>: pour les personnes intéressées: comme pour quoi Faites si vous voulez vraiment transposer em> un tableau 2D en 1D: p> Ceci devrait tirer parti de la mise en cache dans la CPU. J'ai seulement strong> effectué des tests limités à ce sujet - cela pourrait toujours être lent. Essayez de le modifier si c'est.
Vous pouvez (un peu de manière non trivialement) l'étendre à un tableau 3D. P> p>
Ouf, je ne suis pas sûr que vous puissiez obtenir des problèmes avec la mise en page de la mémoire. Les matrices de garantie de spécification sont-elles stockées dans la mémoire mappée séquentielle?
@Johannes: Ils sont Dans l'ordre majeur de la ligne , mais je pense que la colonne-major fonctionnerait également. Vous ne vous souciez pas du rembourrage spécifique à la plate-forme car blockcopy code> devrait en prendre soin de toute façon.
@Mehrdad, alors cela signifie-t-il que je vais obtenir cela dans le résultat?: [Couche 1ère 1ère ligne] [2ème rangée 1ère couche] ... [1er rangée 2ème couche] [2ème rangée 2ème couche] ... ?
@Mehrdad: Bon à savoir, NEVR a travaillé avec BlockCopy, mais heureux cela gère cela.
@Valipour: dépend de ce que vous entendez par "rangée". Dans l'exemple de arr [A, B, C] code>, C i> i> est la ligne, pas a code>. Et dans ce cas, vous passerez à travers la ligne avant de passer à travers la colonne suivante.
@Mehrdad: S'il vous plaît voir mes nouvelles notes dans la question
@Valipour: whoops mon mauvais - c'était une faute de frappe; Bien sûr, B code> est la ligne. Laissez-moi reformuler: la foulée la plus petite i> se produit lorsque vous incrémentez C code>. Je pense que ma réponse fait ce que vous attendez (essayez-le!), Mais je pense que j'ai mal compris ce que vous avez écrit dans votre commentaire - j'ai lu "calque" comme "colonne", donc je pensais que cela ne fait pas ce que vous attendiez ; Cependant, ça fait.
Y a-t-il un moyen pas i> pour copier le tableau?
tampon.blockcopie code> le fera. Au moins, cela fonctionne dans ce test simple. byte[, ,] src = new byte[10, 10, 3];
byte[,] dest = new byte[100, 3];
List<byte> srcList = new List<byte>();
Random rnd = new Random();
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
for (int k = 0; k < 3; ++k)
{
byte b = (byte)rnd.Next();
src[i, j, k] = b;
srcList.Add(b);
}
}
}
Buffer.BlockCopy(src, 0, dest, 0, 300);
List<byte> destList = new List<byte>();
for (int i = 0; i < 100; ++i)
{
for (int j = 0; j < 3; ++j)
{
destList.Add(dest[i, j]);
}
}
// See if they're in the same order
for (int i = 0; i < srcList.Count; ++i)
{
Console.WriteLine("{0,3:N0} - {1,3:N0}", srcList[i], destList[i]);
if (srcList[i] != destList[i])
{
Console.WriteLine("ERROR!");
}
}
Pourquoi ne serait-il pas blockcopy code> prendre soin des problèmes de rembourrage? Les problèmes de rembourrage doivent être transparents au programmeur, c'est donc la la responsabilité i> de blockcopy code> pour le garder de cette façon. (Pensez-y: sinon, cela corrompre votre mémoire!) Il y a aucune raison b> pour éviter blockcopy code> wharse.
Pour d'autres, lisez cette réponse, prenez note que le quatrième paramètre à tampon.BlockCopy est le nombre de octets b> pour copier non la longueur ou le nombre d'éléments à copier. Dans cet exemple, car nous copions des octets, les chiffres sont identiques, mais si votre tampon était un autre type de données comme flottant, n'oubliez pas de multiplier par tailleOf (flotteur) pour copier le nombre correct d'éléments. i.e. tampon.blockcopie (SRCFLOATARRAY, 0, DESTFLOATARRAY, 0, TAILLEOF (FLOAT) * 300);
Autre autrefois, vous voudrez peut-être utiliser System.numerics.tensors A >: Cela facilite le remodelage: p>