2015-04-08 2 views
1

J'avais un C++ .exe que j'utilisais comme nettoyeur d'image autonome. Mais je veux maintenant utiliser sa fonction dans ma propre application C#, j'ai donc commencé à le traduire. Mais je ne connais pas vraiment le C++ et sa logique. Alors je viens ici pour de l'aide.Traduction d'une fonction C++ (traitant avec corona) en C#

D'abord, est-ce que quelqu'un connaît un équivalent pour cette fonction? Corona "getPixels()" (oui avec un "s" parce que je sais C# avoir un getPixel intégré): voici l'explication de la fonction de corona doc: getPixels() Corona dll il est utilisé dans les lignes que je cherche à traduire.

ici est toute la chose:

originale code C++:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "corona.h" 

#define IMAGE_FORMAT corona::PF_R8G8B8 /* RGB mode - 8 bits each */ 
#define GetXY(x,y, w) ((x) + ((w) * (y))) 
#define MIN(a, b) ((a) < (b) ? (a) : (b)) 
#define MAX(a, b) ((a) > (b) ? (a) : (b)) 

#define SQ(a) ((a) * (a)) 
#define DISTANCE(a, b, c, d) (SQ(a - c) + SQ(b - d)) 



int main(int argc, char **argv) 
{ 
corona::Image *img; 
unsigned char *pixels; 
int threshold = 0; 
int distance = 0; 
int pixel; 
char str[255]; 
int rows, cols; 
int row, col; 
unsigned char *bitmap, *p; 
unsigned char *outmap; 
pixels = (unsigned char*)img->getPixels(); 
rows = img->getHeight(); 
cols = img->getWidth(); 
bitmap = new unsigned char[rows * cols]; 
p = bitmap; 
outmap = new unsigned char[rows * cols]; 

//convert to single byte grayscale 
for (row = 0; row < rows; row++) 
for (col = 0; col < cols; col++) 
{ 
    pixel = *pixels++; 
    pixel += *pixels++; 
    pixel += *pixels++; 

    *p++ = pixel/3; 
} 

//free corona loading 
delete img; 

int distance = 8; 
int threshold = 7; 
//check our threshold 
for (row = 0; row < rows; row++) 
for (col = 0; col < cols; col++) 
{ 
    if (bitmap[GetXY(col, row, cols)]) 
    { 
     int count = 0; 
     int x, y; 
     int dhalf = distance/2 + 1; 

     //optimization possible here by checking inside a circle rather than square+dist 
     for (x = MAX(col - dhalf, 0); x < MIN(col + dhalf, cols); x++) 
     for (y = MAX(row - dhalf, 0); y < MIN(row + dhalf, rows); y++) 
     { 
      if (SQ(distance) > DISTANCE(col, row, x, y) && bitmap[GetXY(x, y, cols)]) 
       count++; 
     } 

     if (count >= threshold) 
      outmap[GetXY(col, row, cols)] = 255; 
     else 
      outmap[GetXY(col, row, cols)] = 0; 
    } 
    else 
     outmap[GetXY(col, row, cols)] = 0; 
} 
} 

Ce que je maintenant avec ce que je pourrais traduire ... J'espère bien au moins ...:

private Bitmap optIm2(Bitmap _img) 
     { 
      int rows = _img.Height; 
      int cols = _img.Width; 
      pixels = (unsigned char)img->getPixels(); //here i dont know at all 
      bitmap = new unsigned char[rows * cols]; //here i dont know at all 
      p = bitmap; 
      outmap = new unsigned char[rows * cols]; //here i dont know at all 

      //convert to single byte grayscale 
      for (int row = 0; row < rows; row++) 
      { 
       for (int col = 0; col < cols; col++) 
       { 
        pixel = *pixels++; //here i dont know at all 
        pixel += *pixels++; //here i dont know at all 
        pixel += *pixels++; //here i dont know at all 

        *p++ = pixel/3; //here i dont know at all 
       } 
      } 
      //free corona loading 
      delete img; 

      int distance = 9; 
      int threshold = 7; 

      //check our threshold 
      for (int row = 0; row < rows; row++) 
      { 
       for (int col = 0; col < cols; col++) 
       { 
        if (bitmap[GetXY(col, row, cols)]) 
        { 
         int count = 0; 
         int x, y; 
         int dhalf = distance/2 + 1; 

         //optimization possible here by checking inside a circle rather than square+dist 
         for (x = Math.Max(col - dhalf, 0); x < Math.Min(col + dhalf, cols); x++) 
         { 
          for (y = Math.Max(row - dhalf, 0); y < Math.Min(row + dhalf, rows); y++) 
          { 
           if (SQ(distance) > DISTANCE(col, row, x, y) && bitmap[GetXY(x, y, cols)]) 
            count++; 
          } 
         } 
         if (count >= threshold) 
         { 
          outmap[GetXY(col, row, cols)] = 255; 
         } 
         else 
         { 
          outmap[GetXY(col, row, cols)] = 0; 
         } 
        } 
        else 
        { 
         outmap[GetXY(col, row, cols)] = 0; 
        } 
       } 
      } 
return iDontKnowWhatYet; 
     } 


     private int GetXY(int x,int y, int w) { return ((x) + ((w) * (y))); } 
     private int SQ(int a) { return ((a) * (a)); } 
     private int DISTANCE(int a, int b, int c, int d) { return (SQ(a - c) + SQ(b - d)); } 

Quelqu'un pourrait-il m'aider à comprendre et à convertir ce s'il vous plaît?

Répondre

3

Le code C# ressemblera à quelque chose comme ça

private unsafe Bitmap optIm2(Bitmap img) 
{ 
    int rows = img.Height; 
    int cols = img.Width; 

    var dstImg = new Bitmap(cols, rows, img.PixelFormat); 
    var srcImageData = img.LockBits(new Rectangle(0, 0, cols, rows), System.Drawing.Imaging.ImageLockMode.ReadOnly, img.PixelFormat); 
    var dstImageData = dstImg.LockBits(new Rectangle(0, 0, cols, rows), System.Drawing.Imaging.ImageLockMode.ReadOnly, dstImg.PixelFormat); 
    try 
    { 
     var bitmap = new byte[rows * cols]; 
     var outmap = new byte[rows * cols]; 

     fixed (byte* ptr = &bitmap[0]) 
     { 
      byte* pixels = (byte*)srcImageData.Scan0; 
      byte* p = ptr; 

      //convert to single byte grayscale 
      for (int row = 0; row < rows; row++) 
      { 
       for (int col = 0; col < cols; col++) 
       { 
        var pixel = *pixels++; 
        pixel += *pixels++; 
        pixel += *pixels++; 

        *p++ = (byte)(pixel/3); //here i dont know at all 
       } 
      } 
     } 

     int distance = 9; 
     int threshold = 7; 

     //check our threshold 
     for (int row = 0; row < rows; row++) 
     { 
      for (int col = 0; col < cols; col++) 
      { 
       if (bitmap[GetXY(col, row, cols)] != 0) 
       { 
        int count = 0; 
        int x, y; 
        int dhalf = distance/2 + 1; 

        //optimization possible here by checking inside a circle rather than square+dist 
        for (x = Math.Max(col - dhalf, 0); x < Math.Min(col + dhalf, cols); x++) 
        { 
         for (y = Math.Max(row - dhalf, 0); y < Math.Min(row + dhalf, rows); y++) 
          if ((SQ(distance) > DISTANCE(col, row, x, y)) && (bitmap[GetXY(x, y, cols)] != 0)) 
           count++; 
        } 
        if (count >= threshold) 
         outmap[GetXY(col, row, cols)] = 255; 
        else 
         outmap[GetXY(col, row, cols)] = 0; 
       } 
       else 
        outmap[GetXY(col, row, cols)] = 0; 
      } 
     } 

     // Copy data from outmap to pixels of bitmap. Since outmap is grayscale data, we replicate it for all channels 
     byte* dstPtr = (byte*)dstImageData.Scan0; 
     for (int row = 0; row < rows; row++) 
     { 
      byte* rowPtr = dstPtr; 
      for (int col = 0; col < cols; col++) 
      { 
       *rowPtr++ = outmap[GetXY(col, row, cols)]; 
       *rowPtr++ = outmap[GetXY(col, row, cols)]; 
       *rowPtr++ = outmap[GetXY(col, row, cols)]; 
      } 
      dstPtr += dstImageData.Stride; 
     } 
    } 
    finally 
    { 
     img.UnlockBits(srcImageData); 
     img.Dispose(); 

     dstImg.UnlockBits(dstImageData); 
    } 

    return dstImg; 
} 

private int GetXY(int x, int y, int w) { return ((x) + ((w) * (y))); } 
private int SQ(int a) { return ((a) * (a)); } 
private int DISTANCE(int a, int b, int c, int d) { return (SQ(a - c) + SQ(b - d)); } 

Bien que je ne l'ai pas vérifié votre logique réelle pour l'algorithme correct, le code ci-dessus contient tous les bits que vous devez faire vous-même. Les principaux points à noter sont:

  1. Comment obtenir un pointeur d'un IntPtr (fixe)
  2. Comment obtenir des données de pixels d'un bitmap
  3. Comment écrire des données de pixels vers un bitmap

Espérons que cela aide!

+0

Je ne sais pas si cela fonctionne. mais je vous ai donné un +1 pour l'effort –

+0

@ananthonline Tout d'abord merci beaucoup pour votre temps. Aucune erreur au moins, mais au lieu de renvoyer une image nettoyée, elle retourne un rectangle jaune. Je regarde dans votre code pour vérifier ce qui est fait et pourquoi peut-être son me donnant ceci. +1 de toute façon pour votre temps et votre aide vraiment utile encore – user3916429

+0

@ananthonline pourriez-vous s'il vous plaît me convertir cette dernière chose? cela pourrait résoudre mon problème ... 'unsigned char * pixels = nouveau caractère non signé [width * height * 3]; \t unsigned char * p = pixels, * b = outmap; \t int col, rangée; \t (pour ligne = 0; user3916429