Przekazanie bitmapy ze zdjęciem do biblioteki DLL napisanej w C++

0

Witam potrzebuje pomocy.Tworze aplikacje w C# ,która po wybraniu zdjęć z dysku oraz po wykonaniu pętli wybiera interesujące zdjęcie i chciałbym z C# wysłać to zdjęcie do C++ dll. i w nim wykonać jakieś operacje ,np.zdjęcie w odcieniu szarości oraz zwrócenie z powrotem tego do c#.Proszę o nie mówienie ,że są lepsze sposoby bo taki mam temat pracy magisterskiej.

C# code :

  for (int i = 0; i <= 30; i++)
            {
                if (images[n-1]== images[i])//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                {
                    Bitmap bmp = new Bitmap(images[i]);
                    int width = bmp.Width;//320
                    int height = bmp.Height;//239                    
                    var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                    var bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                    int results = NativeMethods.Gray(bmpData.Width, bmpData.Height, bmpData.Scan0, bmpData.Stride);
                    bmp.UnlockBits(bmpData);
                    image2.Image = bmp;
                }
            }
       
        }
        public static class NativeMethods
        {
            [DllImport("number.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "_Z9AddNumberii")]
            public static extern int Gray(int width, int height, IntPtr scan0, int stride);
        }

C++ dll code :

int Gray(int width, int height, unsigned char *scan0, int stride)
{
	
	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			
			
		}
	}
}

Macie może jakieś pomysły jak wypełnić kod C++ dll oraz powiedzieć czy taki sposób w ogóle jest dobry?

1

Dla RGB/BGR jakoś tak będzie:

int Gray(int width, int height, unsigned char *scan0, int stride)
{
	for (int y = 0; y < height; ++y)
	{
		for (int x = 0, offset = 0; x < width; ++x, offset += 3)
		{
			scan0[offset + 0] = /* ... */; // R lub B 
			scan0[offset + 1] = /* ... */; // G 
			scan0[offset + 2] = /* ... */; // B lub R
		}

		scan0 += stride;
	}
}
0

A ja się zastanawiam po co te kombinacje?
Czy ty naprawdę chcesz zmienić obrazek na skalę szarości (tak sugeruje nazwa funkcji)?
Jeśli tak, to po co ci przeskok do C++?
Jeśli nie, to brakuje kontekstu, co się ma dziać po stronie C++ i czemu właściwie potrzebujesz C++.
Zależnie od okoliczności można podjąć różna działania (np posłużyć się C++ CLI i używać bitmapę bezpośrednio).

0

Przeczytaj jeszcze raz to co napisalem w poscie na samej gorze a bedziesz wiedzial dlaczego potrzebuje C++ i C#

0
/* ... */; // R lub B 

Jak dokladnie odwolac sie w miejscu komentarza dla np.powiedzmy kanalu R ?

0

Wyliczasz skalę szarości ze wzoru 0.21 R + 0.72 G + 0.07 B i przypisujesz otrzymaną wartość do wszystkich kanałów RGB

0

no to rozumiem ale moglbys to wsadzic do kodu jak to przykladowo mialoby wygladac?

0

No nie żartuj. Praktycznie dostałeś gotowy kod, wysil się trochę.

0

Znaczy nie wiem czy dobrze rozumiem o co chodzi :

scan0[offset + 0] =0.21 R ;
scan0[offset + 1] = 0.72 G;
scan0[offset + 2] =   0.07 B;

Cos takiego ?
Tylko co mam wsadzic w miejsce R,G i B bo symulator mi tego nie ogarnie ???

0

A ok juz kumam o co chodzi ,dzieki za pomoc :)

1
Pijany Kot napisał(a):

Przeczytaj jeszcze raz to co napisalem w poscie na samej gorze a bedziesz wiedzial dlaczego potrzebuje C++ i C#

Przeczytałem i tam nic nie ma o tym, czemu to potrzebujesz.
Z opisu wynika, że zarówno kod C++ i C# jest twój.
Gdybyś napisał, że masz bibliotekę C++, która coś tam robi i chcesz jej użyć do obróbki zdjęć, maiło by to sens.
Generalnie takie pomosty mają sens jedynie w przypadku, kiedy po obu stronach masz gotowy kod i chcesz oba kody zmusić do współpracy.

Ze szczątkowego opisu problemu, wynika, że zarówno fragment C# jak i C++ jest nowy i przez ciebie pisany, ergo tracisz czas na coś co nie jest nikomu potrzebne.

Dlatego uważam, ze albo sobie ubzdurałeś jakieś wymagania techniczne, albo jest to problem XY i powinieneś opisać problem pierwotny.

Przez ostatnie 3 lata, pracowałem nad dużą wielkoformatową biblioteką pisaną w C++, która potem była opakowywana przez C#, Java, Objective C zależnie od platformy. Głownie dłubałem przy pomostach Objective C <-> C++, ale zdarzyło mi się robić też C# <-> C++ i o zgrozo Java <-> C++ (JNI).

0

Biblioteka DLL do obróbki zdjec ,taki mam temat pracy magisterskiej i nie wiem czy to jest przydatne komus do zycia czy nie ,czy sie stosuje takie metody w programowania i latanie na dwoch jezykach ,ale musze tak to zrobic i koniec kropka :).

0

W sumie moglby mi ktos wytlumaczyc jednak bo chyba nie do konca wiem o co chodzi :

scan0[offset + 0] =0.21R+0.72G+0.07B  ;
scan0[offset + 1] = 0.21R+0.72G+0.07B ;
scan0[offset + 2] =   0.21R+0.72G+0.07B ;

Jak mam to zapisac od strony programistycznej w miejsach R G i B .Jakas tablice mam wstawic ze scan0 czy jak?

0

ARGB

0
Piotrus Pan napisał(a):

Biblioteka DLL do obróbki zdjec ,taki mam temat pracy magisterskiej i nie wiem czy to jest przydatne komus do zycia czy nie ,czy sie stosuje takie metody w programowania i latanie na dwoch jezykach ,ale musze tak to zrobic i koniec kropka :).

Chwali się, że bierzesz się za magisterkę w listopadzie.
Z drugiej strony nie chce mi się wierzyć, że dokładnie taki masz tytuł pracy magisterskiej! Gdzie/co ty studiujesz?

0

Jak mam to zapisac od strony programistycznej w miejsach R G i B

R to scan0[offset + 1]
G to scan0[offset + 2]
B to scan0[offset + 3]

Dla ARGB offset powinien być zwiększany o 4.

0
int Gray(int width, int height, unsigned char *scan0, int stride)
{
    unsigned char *scanline = scan0;
    for (int y = 0; y < height; ++y)
    {
        for (int x = 0; x < width; ++x)
        {
            // tutaj kolejność niepewna. może argb, może bgra.
            // zakładam że jest argb, dlatego offset + 0 pomijamy bo to kanał alfa którego psuć nie chcemy.
            // mnożenie x*4 dlatego że każdy piksel to cztery bajty.
            unsigned char r = scanline[x * 4 + 1];
            unsigned char g = scanline[x * 4 + 2];
            unsigned char b = scanline[x * 4 + 3];

            unsigned char c = // TODO: wyliczyć poziom szarości na podstawie r, g i b.

            // zapisujemy wyliczone c do kanałów r,g i b. kanału alfa nie ruszamy.
            scanline[x * 4 + 1] = c;
            scanline[x * 4 + 2] = c;
            scanline[x * 4 + 3] = c;
        }
        scanline += stride;
    }
}

jakoś tak.
sposób ze zmienną offset zwiększaną o 4 (zamiast x zwiększanym o 1) jest równoważny.

0

Ok powiedzmy ,że zbudowałem biblioteke w visualu teraz przerzucam ją do c# tym kodem :

public static class NativeMethods
{
[DllImport("Dll1.dll")]
public static extern int Gray(int width, int height, IntPtr scan0, int stride);
}

Wyrzuca mi błąd :
System.DllNotFoundException: 'Nie można załadować biblioteki DLL 'Dll1.dll': Nie można odnaleźć określonego modułu. (Wyjątek od HRESULT: 0x8007007E)'

Chodzi o to ,że nie może znaleźć biblioteki czy odczytać ? Bo visual nieraz dziwnie ocenia sytuacje?
Wrzuciłem biblioteke do pliku exe z projektem

int results = NativeMethods.Gray(bmpData.Width, bmpData.Height, bmpData.Scan0, bmpData.Stride);

Dokładnie w tej linii wyrzuca ten błąd

1 użytkowników online, w tym zalogowanych: 0, gości: 1