Bennu Game Development

Foros en Español => Offtopic => Topic started by: Yawin on April 11, 2011, 10:37:10 AM

Title: Necesito ayuda [C#]
Post by: Yawin on April 11, 2011, 10:37:10 AM
Os explico:
Estoy trabajando con etiquetadoras industriales. Tengo que finalizar un programa que sirve para diseñar las etiquetas y añadirlas al firmware de la etiquetadora, para que imprima cuando haga falta. El tema es que la etiquetadora sólamente acepta imágenes .PCX en modo de color binario/monocromo. Por ello, queremos que el programa, permita abrir cualquier imagen, y cuando envíe la imagen a la impresora, primero la convierta.

Con un simple código, soy capaz de capturar el color de cada pixel y calcular si tiene que ser negro o blanco (dependiendo de la intensidad que se le marque); y, con una librería que me he encontraod por ahí, puedo convertir a PCX.

Pero, aun así, la imagen no es monocromo. Y no se cómo carajo hacerlo. Y no encuentro documentación por ahí.

¿Sabe alguno de vosotros qué puedo hacer?
Title: Re: Necesito ayuda [C#]
Post by: FreeYourMind on April 11, 2011, 10:42:27 AM
http://www.codeproject.com/search.aspx?q=image+converter+c%23&sbo=kw (http://www.codeproject.com/search.aspx?q=image+converter+c%23&sbo=kw)
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 11, 2011, 11:20:32 AM
He estado mirando los links que salen ahí. Pero son diferentes algoritmos para pasar una imagen a blanco y negro. Esa parte ya la tengo.

Realmente, lo único que no tengo, es que alguardar la imagen, en el fichero se grabe como PCX Monocromo
Title: Re: Necesito ayuda [C#]
Post by: SplinterGU on April 11, 2011, 01:46:07 PM
en el foro alguien puso un algoritmo de dither y el formato pcx es muy simple y lo encontras en internet, con eso ya podes armarte una simple implementacion para lo que necesitas.
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 11, 2011, 01:49:27 PM
Del formato pcx no hay tanto como parece en internet.

Y qué es eso de Algoritmo de dither??
Title: Re: Necesito ayuda [C#]
Post by: SplinterGU on April 11, 2011, 01:52:10 PM
el algoritmo de dither pasa una imagen a color en blanco y negro (2 colores)

en realidad es un algoritmo que sirve para bajar la cantidad de colores de un grafico, reemplazando los colores inexistentes por una mezcla de pixels de colores que si existen, pero se usa (usaba) mucho para convertir de color a blanco y negro.

la primera busqueda que aparece en google si pones "formato pcx" es

http://es.wikipedia.org/wiki/PCX

ahi tenes la info necesaria.
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 11, 2011, 01:59:47 PM
Creo que no me explico bien. A ver...
No tengo problemas con pasarlo a blanco y negro. el algoritmo me funciona fetén:

            for (int x = int.Parse((bmp2.PhysicalDimension.Width - 1).ToString()); x >= 0; x--)
            {
                for (int y = int.Parse((bmp2.PhysicalDimension.Height - 1).ToString()); y >= 0; y--)
                {
                    bmp2.SetPixel(x, y, bmp3.GetPixel(x, y));
                }
            }
            for (int x = int.Parse((bmp2.PhysicalDimension.Width - 1).ToString()); x >= 0; x--)
            {
                for (int y = int.Parse((bmp2.PhysicalDimension.Height - 1).ToString()); y >= 0; y--)
                {
                    Color col = bmp2.GetPixel(x, y);

                    int media = (col.R + col.G + col.B) / 3;
                    media = (media * 100) / 255;

                    if (media > por)
                    {
                        col = Color.White;
                    }
                    else
                    {
                        col = Color.Black;
                    }

                    bmp2.SetPixel(x, y, col);
                }
            }
            pictureBox1.Image = bmp2;


Tampoco tengo problemas para guardarlo en .PCX

Mi problema está en que aunque sea blanco y negro y sea .pcx la impresora me dice que la imagen, el archivo, no es monocromo.
Title: Re: Necesito ayuda [C#]
Post by: SplinterGU on April 11, 2011, 02:07:43 PM
pues caramba...

si que tienes problemas para grabarlo, porque el byte 3 de la cabecera indica como es el archivo, para monocromo, no tenes que solo pasarlo a blanco y negro, sino que tenes que setear el byte 3 (empezando a contar desde 0) a 1, para indicar que es 1bit por pixel, y por ende monocromo.

demas esta decir que no lo podes hacer en el mismo bmp, porque el bmp original no es de 1bpp... como veo estas haciendo en el codigo que pegaste.

el destino (monocromo) debe ser de 1bpp.

aca tenes otro link

http://courses.engr.illinois.edu/ece390/books/labmanual/graphics-pcx.html

por otro lado te recomiento el algoritmo de dither, eso de poner un color u otro en base a la media, va a hacer que muchas imagenes directamente no aparezcan o aparezcan como una mancha negra.
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 11, 2011, 03:11:12 PM
Gracias, miraré ese link en cuanto llegue a casa (esque ya acabo de trabajar).

Y no voy a usar ese algoritmo porque:
El usuario tiene una trackbar para nivelar la cantidad de negro. Ten en cuenta que este programa no va a trabajar con degradados y cosas así, sino con logos de empresas. Los logos no suelen tener más de 3 colores.
Title: Re: Necesito ayuda [C#]
Post by: SplinterGU on April 11, 2011, 03:36:12 PM
mas alla de lo que quieras hacer es bueno completar la informacion al respecto...

aca hay una clara imagen de lo que vos estas haciendo...

(http://www.izotope.com/tech/mbit/images/visual_dither.gif)

en el grafico anterior, se muestra la imagen original, la imagen de 1bit truncado (o umbral), y la imagen de 1bit dithered... la diferencia es clara...

si los logos pueden tener mas de 2 colores entonces (en mi opinion) es necesario que pongas una buena conversion, ademas de que el algoritmo es sumamente estupido...

aca pongo mas imagenes...

(http://www.uv.es/gpoei/eng/Pfc_web/generalidades/fig42.gif)

otra

(http://img340.imageshack.us/img340/8872/modebitmap.jpg)

ampliada

(http://img340.imageshack.us/img340/5850/modebitmapzoom.jpg)

original

(http://img44.imageshack.us/img44/2825/modergb.jpg)

links

http://www.uv.es/gpoei/eng/Pfc_web/generalidades/dithering.htm

bien, en fin, tu decides que usar, aca estan explicados y mostrados los resultados de la tecnica y la informacion para que puedas hacer un pcx monocromo.
Title: Re: Necesito ayuda [C#]
Post by: Fede on April 11, 2011, 03:48:09 PM
Si estáis buscando esto.  ;D

http://forum.bennugd.org/index.php?topic=1927.0
Title: Re: Necesito ayuda [C#]
Post by: Drumpi on April 11, 2011, 06:15:25 PM
Yo creo que es porque usa una librería externa para convertir a PCX. Es probable que coja esa imágen y, aunque use 2 colores, la guarde a 16 o 24 bits de color. Mira a ver qué te dicen otros programas de ediciónde imágen sobre los PCX generados, si son de 1bit o de más.
Sólo tendrías que mirar cómo se crean mapas de 1 bit con esa librería o, en última instancia, crearte tu propio algoritmo de guardado, no parece un formato demasiado complicado de implementar.
Title: Re: Necesito ayuda [C#]
Post by: SplinterGU on April 11, 2011, 06:31:44 PM
drumpi, si miras el codigo esta haciendo esto

color = get_pixel(mapaoriginal, x, y)
convertir color a 2 colores
put_pixel(mapaorigina,x,y,nuevocolor)

como se ve, usa mapaoriginal (bmp2) y si mapaoriginal es un un RGB (16 o mas bpp) nunca lo podra grabar a 1bpp sin convertirlo.
Title: Re: Necesito ayuda [C#]
Post by: l1nk3rn3l on April 12, 2011, 03:31:11 AM
http://www.imagemagick.org/script/formats.php

http://es.kioskea.net/faq/2363-imagemagic-editar-imagenes-desde-la-linea-de-comandos

http://www.imagemagick.org/Usage/quantize/#monochrome

ese mismo soporta c# y linea de comandos sino quieres meterte con codigo


aqui las funciones principales (es un monstruo esta libreria)
http://www.imagemagick.org/Usage/


permite usar el api desde c++ / c# / php y otros , pero recomiendo mejor
usar la linea de comandos y que el mismo "convert.exe" se encargue de todo
solo preocupate de generar un bmp desde c# jejejeje, lo cual es inmediato..
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 12, 2011, 06:27:37 AM
Quote from: SplinterGU on April 11, 2011, 06:31:44 PM
drumpi, si miras el codigo esta haciendo esto

color = get_pixel(mapaoriginal, x, y)
convertir color a 2 colores
put_pixel(mapaorigina,x,y,nuevocolor)

como se ve, usa mapaoriginal (bmp2) y si mapaoriginal es un un RGB (16 o mas bpp) nunca lo podra grabar a 1bpp sin convertirlo.
No verás, lo que hago es:
Cargo en un bitmap una imagen
color = get_pixel(mapaoriginal, x, y)
put_pixel(nuevo bitmap,x,y,mismo color)

Y luego ya:
color = get_pixel(mapaoriginal, x, y)
convertir color a 2 colores
put_pixel(mapaorigina,x,y,nuevocolor)

Esqye si no, me decía todo el rato que el otro fichero estaba abierto.
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 12, 2011, 08:23:35 AM
¿Y cómo puedo modificar la cabecera del pcx?
Porque si abro la imagen así:
private void Form2_Load(object sender, EventArgs e)
        {
            string tex,texto="",fic="C:/Documents and Settings/miguel.albors/Escritorio/conversiones/conversión.pcx";

            System.IO.StreamReader sr = new System.IO.StreamReader(fic);
            do
            {
                tex = sr.ReadLine();
                if (tex != null)
                {
                    texto += tex;
                }
            } while (tex != null);
            sr.Close();

            richTextBox1.Text += texto;
        }


No me recupera nada que se pueda entender.
Title: Re: Necesito ayuda [C#]
Post by: FreeYourMind on April 12, 2011, 09:05:11 AM
No pongas rutas relativas en el codigo, utiliza una key del app.config para leer la ruta y así la puedes cambiar cuando distribuyas la aplicación.

Sobre el codigo lo estas abriendo como texto, creo que lo debes abrir como binario (binary.read en lugar de stream.read).
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 12, 2011, 09:57:02 AM
Verás, lo de las rutas es algo que, sinceramente, me la trae floja. Eso es sólo una aplicación de test. Para, una vez logrado ahí lo que quiero integrarlo en el programa bueno.
Title: Re: Necesito ayuda [C#]
Post by: SplinterGU on April 12, 2011, 03:43:55 PM
primero, la data que generas no es monocroma, solo convertir un grafico de mas de 2 colores a escala de grises (aunque sean 2 colores) que no es lo mismo.

es lo que digo, estas usando el mismo mapa origen (origen para la conversion, no importa si lo copias antes de usarlo, es el origen a fines de la conversion) para el destino... y eso no es correcto, porque suponiendo que la imagen origen es de 8bpp (256 colores) entonces 1 pixel es 1 byte, pero para un pcx monocromo, tenes 1 byte representan 8 pixels.

no es solo cambiar la cabecera, lo que yo dije es una parte de lo que tenes que hacer y no podes solo cambiar, tenes que crear el archivo pcx (por eso decia que te armes el algoritmo para guardar el archivo) y ademas pasar de byte/word/lo que sea, a bits.
Title: Re: Necesito ayuda [C#]
Post by: FreeYourMind on April 12, 2011, 05:20:56 PM
Te paso un programa que hice hace bastantes años, que genera una bmp (en la raiz de la unidad, la segunda vez da error porque no controla que ya existe el fichero bmp y hay que borrarlo o numerar los bmp generados), se ve como recorrer la imagen y como generar la cabecera bmp, a ver si con esto lo puedes adaptar a tu codigo para generar un pcx:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace PAI_1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Button button2;

//our variables
public struct BM_FILEHEADER
{
public ushort type;
public uint size;
public ushort reserved1;
public ushort reserved2;
public uint offset;
}

public struct BM_INFOHEADER
{
public uint headersize;
public int width;
public int height;
public ushort planes;
public ushort bpp;
public int compression;
public uint sizeimage;
public int Xppm;
public int Yppm;
public uint ColorsUsed;
public uint ColorsImportant;
}

public struct BM_RGBQUAD
{
byte rgbBlue;
byte rgbGreen;
byte rgbRed;
byte rgbReserved;
}

/// <summary>
/// Required designer variable.
/// </summary>





private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(16, 32);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(144, 32);
this.button1.TabIndex = 0;
this.button1.Text = "1.1 - Imagem branca com QUAD preto centrado";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label1
//
this.label1.Location = new System.Drawing.Point(440, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(104, 24);
this.label1.TabIndex = 1;
this.label1.Text = "label1";
//
// label2
//
this.label2.Location = new System.Drawing.Point(440, 32);
this.label2.Name = "label2";
this.label2.TabIndex = 2;
this.label2.Text = "label2";
//
// label3
//
this.label3.Location = new System.Drawing.Point(440, 56);
this.label3.Name = "label3";
this.label3.TabIndex = 3;
this.label3.Text = "label3";
//
// label4
//
this.label4.Location = new System.Drawing.Point(440, 80);
this.label4.Name = "label4";
this.label4.TabIndex = 4;
this.label4.Text = "label4";
//
// button2
//
this.button2.Location = new System.Drawing.Point(16, 72);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(144, 32);
this.button2.TabIndex = 5;
this.button2.Text = "1.2 - Degradé duplo de Preto -> Branco";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(560, 358);
this.Controls.Add(this.button2);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
BM_FILEHEADER FileHeader = new BM_FILEHEADER();

BM_INFOHEADER InfoHeader = new BM_INFOHEADER();

// EXERCICIO 1.1
// EXERCICIO 1.1
// EXERCICIO 1.1
private void button1_Click(object sender, System.EventArgs e)
{
//Atribuição às variaveis FileHeader
FileHeader.type=19778;//"BM"
FileHeader.size = 54+512*512;//512*512;
FileHeader.reserved1 = 0;
FileHeader.reserved2 = 0;
FileHeader.offset = 54; //54bytes do HEADDER + 1024 da Pallete
//Atribuição às variaveis InfoHeader
InfoHeader.headersize = 40;
InfoHeader.width = 512;
InfoHeader.height = 512;
InfoHeader.planes = 1;
InfoHeader.bpp = 8;
InfoHeader.compression = 0;
InfoHeader.sizeimage = (uint)(InfoHeader.width *InfoHeader.height*(InfoHeader.bpp/8));//54 + 1024 + 512*512;
InfoHeader.Xppm = 0;
InfoHeader.Yppm = 0;
InfoHeader.ColorsUsed = 256;
InfoHeader.ColorsImportant = 0;
//PALLETE
byte[] palleteBMP = new byte[1024];
int i =0;
for (uint j=0;j<256;j++)
{
palleteBMP[i++]=(byte)j;
palleteBMP[i++]=(byte)j;
palleteBMP[i++]=(byte)j;
palleteBMP[i++]=(byte)0;

}
//IMAGEM----------------------------------------------
byte[] pixels = new byte[512*512];
//first white
for(int line=0; line<128;line++)
for(int col=0; col<512; col++)
pixels[(512*line)+col]=(byte)255;
//middle
for (int line=128;line<384;line++)
{
//lado esquerdo white
for (int col=0; col<128; col++)
pixels[(512*line)+col]=(byte)255;
//preto
for (int col=128; col<384; col++)
pixels[(512*line)+col]=(byte)0;
//lado direito
for (int col=384; col<512; col++)
pixels[(512*line)+col]=(byte)255;
}
//last white
for (int line=384;line<512;line++)
for (int col=0;col<512;col++)
pixels[(512*line)+col]=(byte)255;
//ESCRITA------------------------------------------
BinaryWriter Bitmap_File=new BinaryWriter(new FileStream("D:\\BMP_1_1.bmp", FileMode.CreateNew));
//escrita do cabeçalho
Bitmap_File.Write(FileHeader.type);
Bitmap_File.Write(FileHeader.size);
Bitmap_File.Write(FileHeader.reserved1);
Bitmap_File.Write(FileHeader.reserved2);
Bitmap_File.Write(FileHeader.offset);
//escrita do cabeçalho InfoHeader
Bitmap_File.Write(InfoHeader.headersize);
Bitmap_File.Write(InfoHeader.width);
Bitmap_File.Write(InfoHeader.height);
Bitmap_File.Write(InfoHeader.planes);
Bitmap_File.Write(InfoHeader.bpp);
Bitmap_File.Write(InfoHeader.compression);
Bitmap_File.Write(InfoHeader.sizeimage);
Bitmap_File.Write(InfoHeader.Xppm);
Bitmap_File.Write(InfoHeader.Yppm);
Bitmap_File.Write(InfoHeader.ColorsUsed);
Bitmap_File.Write(InfoHeader.ColorsImportant);
//escrita da pallete
for (int l=0;l<1024;l++)
Bitmap_File.Write(palleteBMP[l]);
//escrita da imagem
for (int p=0;p<pixels.Length;p++)
Bitmap_File.Write(pixels[p]);
//fim
Bitmap_File.Close();

}


// EXERCICIO 1.2
// EXERCICIO 1.2
// EXERCICIO 1.2
private void button2_Click(object sender, System.EventArgs e)
{
//Atribuição às variaveis FileHeader
FileHeader.type=19778;//"BM"
FileHeader.size = 54+512*512;//512*512;
FileHeader.reserved1 = 0;
FileHeader.reserved2 = 0;
FileHeader.offset = 54; //54bytes do HEADDER + 1024 da Pallete
//Atribuição às variaveis InfoHeader
InfoHeader.headersize = 40;
InfoHeader.width = 512;
InfoHeader.height = 512;
InfoHeader.planes = 1;
InfoHeader.bpp = 8;
InfoHeader.compression = 0;
InfoHeader.sizeimage = (uint)(InfoHeader.width *InfoHeader.height*(InfoHeader.bpp/8));//54 + 1024 + 512*512;
InfoHeader.Xppm = 0;
InfoHeader.Yppm = 0;
InfoHeader.ColorsUsed = 256;
InfoHeader.ColorsImportant = 0;
//PALLETE
byte[] palleteBMP = new byte[1024];
int i =0;
for (uint j=0;j<256;j++)
{
palleteBMP[i++]=(byte)j;
palleteBMP[i++]=(byte)j;
palleteBMP[i++]=(byte)j;
palleteBMP[i++]=(byte)0;

}
//IMAGEM----------------------------------------------
byte[] pixels = new byte[512*512];
//first white
for(int line=0; line<512;line++)
{
for(int col=0; col<256; col++)
pixels[(512*line)+col]=(byte)col;
for(int col=256; col<512; col++)
pixels[(512*line)+col]=(byte)col;
}

//ESCRITA------------------------------------------
BinaryWriter Bitmap_File=new BinaryWriter(new FileStream("D:\\BMP_1_2.bmp", FileMode.CreateNew));
//escrita do cabeçalho
Bitmap_File.Write(FileHeader.type);
Bitmap_File.Write(FileHeader.size);
Bitmap_File.Write(FileHeader.reserved1);
Bitmap_File.Write(FileHeader.reserved2);
Bitmap_File.Write(FileHeader.offset);
//escrita do cabeçalho InfoHeader
Bitmap_File.Write(InfoHeader.headersize);
Bitmap_File.Write(InfoHeader.width);
Bitmap_File.Write(InfoHeader.height);
Bitmap_File.Write(InfoHeader.planes);
Bitmap_File.Write(InfoHeader.bpp);
Bitmap_File.Write(InfoHeader.compression);
Bitmap_File.Write(InfoHeader.sizeimage);
Bitmap_File.Write(InfoHeader.Xppm);
Bitmap_File.Write(InfoHeader.Yppm);
Bitmap_File.Write(InfoHeader.ColorsUsed);
Bitmap_File.Write(InfoHeader.ColorsImportant);
//escrita da pallete
for (int l=0;l<1024;l++)
Bitmap_File.Write(palleteBMP[l]);
//escrita da imagem
for (int p=0;p<pixels.Length;p++)
Bitmap_File.Write(pixels[p]);
//fim
Bitmap_File.Close();
}


}
}




Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 12, 2011, 05:43:04 PM
Muchas gracias. No entiendo ni papa, pero tengo una compañera de curro que es ingeniera y fijo que lo entiende. Le pediré "halluda" jajajajaja
Title: Re: Necesito ayuda [C#]
Post by: l1nk3rn3l on April 12, 2011, 09:41:46 PM
Quote from: yawin on April 12, 2011, 05:43:04 PM
Muchas gracias. No entiendo ni papa, pero tengo una compañera de curro que es ingeniera y fijo que lo entiende. Le pediré "halluda" jajajajaja

con image magic conviertes lo que deseas en una sola linea...


http://stackoverflow.com/questions/1417064/exec-imagemagick-convert-via-c


y aqui el ejemplo de monocromo

http://www.imagemagick.org/Usage/quantize/#monochrome
Title: Re: Necesito ayuda [C#]
Post by: Yawin on April 12, 2011, 10:07:54 PM
¿Sabes qué pasa? Que el jefe de mi proyecto prefiere no depender de cosas externas. Y ya dependemos de unas cuantas librerías externas. el proyecto es comercial, asi que tampoco podemos depender de cualquier cosa.

a parte, estoy para aprender, por tanto, si lo puedo hacer yo, prefiero hacerlo yo a cojerlo hecho.

Pero se agradece la ayuda.
Title: Re: Necesito ayuda [C#]
Post by: folken on April 14, 2011, 05:51:01 AM
Hola,  :) creo que podrias hacerlo de una mejor manera con una dll nativa de windows bien sea API Win32 o una DLL MFC, podrias usar el GDI del kernel, hay bastantes funciones para hacer ese tipo de cosas, por mucho que esten especializadas las clases del .NET, operaciones de bajo nivel con archivos de imagenes siempre resulta mejor y mas practico hacerlas con el API o las MFC.

se me ocurre que pudieras hacer un dll API o MFC, y si lo necesitas implementar en C# recuerda que puedes usar:
InteropServices para invocar modulos que no son .NET

-----------------------------------------------------------------

using System.Runtime.InteropServices;


[DllImport("msvcrt.dll")]
internal static extern long Tufuncion();




Y por otras razones de performance me parece que no te conviene hacer ese tipo de conversiones con .NET,  el codigo MSIL que produce el compilador no es muy eficiente y aparte al ser ejecutado por el JIT en un overheap administrado no son nada optimos , si ejecutas el procesamiento de varias imagenes de manera repetido y abundante, para manejo en terminos de performance y consumo de recursos de hardware te recomendaria hacerlo con el API o las MFC.


Saludos!!!!!!