2015-04-08 2 views
1

У меня был C++ .exe, который я использовал в качестве автономного очистителя изображений. Но теперь я хочу использовать его fonction в моем собственном приложении C#, поэтому я начал его переводить. Но я ДЕЙСТВИТЕЛЬНО ОБЯЗАТЕЛЬНО ничего не знаю о C++ и его логике. Так что я прихожу сюда за помощью.Перевод функции C++ (работа с короной) на C#

Во-первых, кто-нибудь знает какой-либо эквивалент этой функции? Corona «getPixels()» (да с «s», потому что я знаю, что C# имеет встроенный getPixel): здесь объяснение функции от corona doc: getPixels() Corona dll используется в строках, которые я ищу для перевода.

здесь все дело:

оригинальный 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; 
} 
} 

Что я теперь с тем, что я мог бы перевести ... я надеюсь, что правильно, по крайней мере ...:

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)); } 

Может ли кто-нибудь помочь мне понять и преобразовать это, пожалуйста?

ответ

3

C# код будет выглядеть примерно как этот

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)); } 

В то время как я не проверил фактическую логику для правильного алгоритма, приведенный выше код содержит все биты, нужно, чтобы сделать это самостоятельно. Основные моменты, следует отметить:

  1. Как получить указатель из IntPtr (фиксированный)
  2. Как получить пиксельные данные из растрового изображения
  3. Как писать пиксельные данные обратно в растр

Надеюсь, это поможет!

+0

Я не знаю, работает ли это. но я дал вам +1 за усилие –

+0

@ananthonline Прежде всего, спасибо большое за ваше время. По крайней мере, ошибок нет, но вместо возврата очищенного изображения возвращается желтый прямоугольник. Я просматриваю ваш код, чтобы проверить, что сделано, и почему, возможно, это дает мне это. +1 в любом случае для вашего времени и вашей действительно полезной помощи снова – user3916429

+0

@ananthonline, можете ли вы, пожалуйста, преобразовать меня в эту последнюю вещь? он может исправить мою проблему ... 'unsigned char * pixels = new unsigned char [width * height * 3]; \t unsigned char * p = pixels, * b = outmap; \t int col, row; \t для (строка = 0; строк <строк; строка ++) \t для (COL = 0; Col user3916429

Смежные вопросы