Avatar billede basementjack Nybegynder
11. november 2004 - 20:38 Der er 14 kommentarer og
1 løsning

billede resizing component

Jeg skal til at lave noget billede resizing på et site, så tænkte jeg at man lige så godt kunne lave et component.. Men alle de steder på nettet, man kan læse om image resizing, er det on-the-fly resizing.. Jeg skal have det billede jeg har uploadet resizet og have det resizede billede gemt...
Nogen der har et stk kode der ligger og flyder?.. :)
Avatar billede burningice Nybegynder
11. november 2004 - 21:12 #1
public static Bitmap Resize(Bitmap b, int nWidth, int nHeight, bool bBilinear)
        {
            Bitmap bTemp = (Bitmap)b.Clone();
            b = new Bitmap(nWidth, nHeight, bTemp.PixelFormat);

            double nXFactor = (double)bTemp.Width/(double)nWidth;
            double nYFactor = (double)bTemp.Height/(double)nHeight;

            if (bBilinear)
            {
                double fraction_x, fraction_y, one_minus_x, one_minus_y;
                int ceil_x, ceil_y, floor_x, floor_y;
                Color c1 = new Color();
                Color c2 = new Color();
                Color c3 = new Color();
                Color c4 = new Color();
                byte red, green, blue;

                byte b1, b2;

                for (int x = 0; x < b.Width; ++x)
                    for (int y = 0; y < b.Height; ++y)
                    {
                        // Setup

                        floor_x = (int)Math.Floor(x * nXFactor);
                        floor_y = (int)Math.Floor(y * nYFactor);
                        ceil_x = floor_x + 1;
                        if (ceil_x >= bTemp.Width) ceil_x = floor_x;
                        ceil_y = floor_y + 1;
                        if (ceil_y >= bTemp.Height) ceil_y = floor_y;
                        fraction_x = x * nXFactor - floor_x;
                        fraction_y = y * nYFactor - floor_y;
                        one_minus_x = 1.0 - fraction_x;
                        one_minus_y = 1.0 - fraction_y;

                        c1 = bTemp.GetPixel(floor_x, floor_y);
                        c2 = bTemp.GetPixel(ceil_x, floor_y);
                        c3 = bTemp.GetPixel(floor_x, ceil_y);
                        c4 = bTemp.GetPixel(ceil_x, ceil_y);

                        // Blue
                        b1 = (byte)(one_minus_x * c1.B + fraction_x * c2.B);

                        b2 = (byte)(one_minus_x * c3.B + fraction_x * c4.B);
                       
                        blue = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));

                        // Green
                        b1 = (byte)(one_minus_x * c1.G + fraction_x * c2.G);

                        b2 = (byte)(one_minus_x * c3.G + fraction_x * c4.G);
                       
                        green = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));

                        // Red
                        b1 = (byte)(one_minus_x * c1.R + fraction_x * c2.R);

                        b2 = (byte)(one_minus_x * c3.R + fraction_x * c4.R);
                       
                        red = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));

                        b.SetPixel(x,y, System.Drawing.Color.FromArgb(255, red, green, blue));
                    }
            }
            else
            {
                for (int x = 0; x < b.Width; ++x)
                    for (int y = 0; y < b.Height; ++y)
                        b.SetPixel(x, y, bTemp.GetPixel((int)(Math.Floor(x * nXFactor)),(int)(Math.Floor(y * nYFactor))));
            }

            return b;
        }
Avatar billede basementjack Nybegynder
11. november 2004 - 21:18 #2
Og så hva gør man ind i mellem?

Du får din fil fra en HTMLInputFile og så sender det din Resize function sådan her .... derefter gemmer du det returnerede bitmap ved at .... ?

Og så i Vb for de andre, der kigger med. :)
cyberfessor - du må gerne skrive videre i C#..

vb________________________________________
Public Shared Function Resize(ByVal b As Bitmap, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bBilinear As Boolean) As Bitmap
Dim bTemp As Bitmap = CType(b.Clone(), Bitmap)
b = New Bitmap (nWidth, nHeight, bTemp.PixelFormat)
Dim nXFactor As Double = CType(bTemp.Width, Double) / CType(nWidth, Double)
Dim nYFactor As Double = CType(bTemp.Height, Double) / CType(nHeight, Double)
If bBilinear Then
  Dim fraction_x As Double
  Dim fraction_y As Double
  Dim one_minus_x As Double
  Dim one_minus_y As Double
  Dim ceil_x As Integer
  Dim ceil_y As Integer
  Dim floor_x As Integer
  Dim floor_y As Integer
  Dim c1 As Color = New Color ()
  Dim c2 As Color = New Color ()
  Dim c3 As Color = New Color ()
  Dim c4 As Color = New Color ()
  Dim red As Byte
  Dim green As Byte
  Dim blue As Byte
  Dim b1 As Byte
  Dim b2 As Byte
  Dim x As Integer = 0
  While x < b.Width
    Dim y As Integer = 0
    While y < b.Height
      floor_x = CType(Math.Floor(x * nXFactor), Integer)
      floor_y = CType(Math.Floor(y * nYFactor), Integer)
      ceil_x = floor_x + 1
      If ceil_x >= bTemp.Width Then
        ceil_x = floor_x
      End If
      ceil_y = floor_y + 1
      If ceil_y >= bTemp.Height Then
        ceil_y = floor_y
      End If
      fraction_x = x * nXFactor - floor_x
      fraction_y = y * nYFactor - floor_y
      one_minus_x = 1 - fraction_x
      one_minus_y = 1 - fraction_y
      c1 = bTemp.GetPixel(floor_x, floor_y)
      c2 = bTemp.GetPixel(ceil_x, floor_y)
      c3 = bTemp.GetPixel(floor_x, ceil_y)
      c4 = bTemp.GetPixel(ceil_x, ceil_y)
      b1 = CType((one_minus_x * c1.B + fraction_x * c2.B), Byte)
      b2 = CType((one_minus_x * c3.B + fraction_x * c4.B), Byte)
      blue = CType((one_minus_y * CType(CType(fraction_y, b1), Double) * CType((b2), Double)), Byte)
      b1 = CType((one_minus_x * c1.G + fraction_x * c2.G), Byte)
      b2 = CType((one_minus_x * c3.G + fraction_x * c4.G), Byte)
      green = CType((one_minus_y * CType(CType(fraction_y, b1), Double) * CType((b2), Double)), Byte)
      b1 = CType((one_minus_x * c1.R + fraction_x * c2.R), Byte)
      b2 = CType((one_minus_x * c3.R + fraction_x * c4.R), Byte)
      red = CType((one_minus_y * CType(CType(fraction_y, b1), Double) * CType((b2), Double)), Byte)
      b.SetPixel(x, y, System.Drawing.Color.FromArgb(255, red, green, blue))
      ConversionHelpers.Increment (y)
    End While
    ConversionHelpers.Increment (x)
  End While
Else
  Dim x As Integer = 0
  While x < b.Width
    Dim y As Integer = 0
    While y < b.Height
      b.SetPixel(x, y, bTemp.GetPixel(CType((Math.Floor(x * nXFactor)), Integer), CType((Math.Floor(y * nYFactor)), Integer)))
      ConversionHelpers.Increment (y)
    End While
    ConversionHelpers.Increment (x)
  End While
End If
Return b
End Function
Avatar billede burningice Nybegynder
11. november 2004 - 21:24 #3
well... den her funktion er lavet så den fungerer uafhængigt at konteksten.

i dit tilfælde vil det blive til noget i retningen af

1) Brugeren uploader en fil
2) du laver et bitmap-object ud af filen
3) Kalder resize-funktionen på dit bitmap
4) bruger Bitmaps Save()-funktion til at gemme billedet ned på harddisken
Avatar billede basementjack Nybegynder
11. november 2004 - 22:31 #4
Når jeg forsøger at kompliere vil den ikke godtage b1, b2 og b3.. Og den kan ikke finde ConversionHelpers, jeg kan ikke lige finde den klasse som indeholder den..
Avatar billede burningice Nybegynder
12. november 2004 - 11:02 #5
lad mig gætte... du har brugt en eller anden form for auto c#->vb.net converter? :)
Avatar billede basementjack Nybegynder
12. november 2004 - 17:38 #6
Skyldig.. :)
Avatar billede basementjack Nybegynder
12. november 2004 - 19:50 #7
Okay.. Det punkt som compileren brokker sig over, forstår jeg godt den ikke kan li.. Og når jeg ser på samme punkt i dit C#, så forstår jeg heller ikke at det virker..

Man laver to bytes b1 og b2... Og senere der hvor man laver en color, bruger b1 og b2 som Double...

byte b1, b2;
....
blue = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));

Kan du kaste lys over det der?
Avatar billede burningice Nybegynder
12. november 2004 - 21:22 #8
det er fordi at en byte kan repræsentere tallene fra 0 til 255...

lad os sige at b2 indeholder 00010010... så vil en casting til double give tallet 18

så...

blue = (byte)(one_minus_y * (double)(00010011) + fraction_y * (double)(00010010));

=>

blue = (byte)(one_minus_y * 19 + fraction_y * 18);

=>

(byte)(et_eller_andet_tal (f.eks. 87));

=>

(byte)(87) = 01010111


så der er skam ikke noget mystifystisk over det... men hvordan man laver en sådan konvertering i vb.net
Avatar billede basementjack Nybegynder
12. november 2004 - 21:27 #9
Jeg tror at oversættelse ikke skulle være:
blue = CType((one_minus_y * CType(CType(fraction_y, b1), Double) * CType((b2), Double)), Byte)
Men :
blue = CType((one_minus_y * CType(b1, Double) + fraction_y * CType((b2), Double)), Byte)

Jeg kigger liige lidt mere på det..
Avatar billede basementjack Nybegynder
12. november 2004 - 23:38 #10
Okay.. Det virker nu.. Smid et svar..
Hvis du har en god workaround på http://support.microsoft.com/?id=814675 så må du meget gerne vise den her, for deres egen løsningsforslag kan jeg ikke få til at virke..

Til andre, koden i vb som virker:

vb______________________________
    Public Shared Function Resize(ByVal b As Bitmap, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bBilinear As Boolean) As Bitmap
        Dim bTemp As Bitmap = CType(b.Clone(), Bitmap)
        b = New Bitmap (nWidth, nHeight, bTemp.PixelFormat)
        Dim nXFactor As Double = CType(bTemp.Width, Double) / CType(nWidth, Double)
        Dim nYFactor As Double = CType(bTemp.Height, Double) / CType(nHeight, Double)
        If bBilinear Then
            Dim fraction_x As Double
            Dim fraction_y As Double
            Dim one_minus_x As Double
            Dim one_minus_y As Double
            Dim ceil_x As Integer
            Dim ceil_y As Integer
            Dim floor_x As Integer
            Dim floor_y As Integer
            Dim c1 As Color = New Color ()
            Dim c2 As Color = New Color ()
            Dim c3 As Color = New Color ()
            Dim c4 As Color = New Color ()
            Dim red As Byte
            Dim green As Byte
            Dim blue As Byte
            Dim b1 As Byte
            Dim b2 As Byte
            Dim x As Integer = 0
            While x < b.Width
                Dim y As Integer = 0
                While y < b.Height
                    floor_x = CType(Math.Floor(x * nXFactor), Integer)
                    floor_y = CType(Math.Floor(y * nYFactor), Integer)
                    ceil_x = floor_x + 1
                    If ceil_x >= bTemp.Width Then
                        ceil_x = floor_x
                    End If
                    ceil_y = floor_y + 1
                    If ceil_y >= bTemp.Height Then
                        ceil_y = floor_y
                    End If
                    fraction_x = x * nXFactor - floor_x
                    fraction_y = y * nYFactor - floor_y
                    one_minus_x = 1 - fraction_x
                    one_minus_y = 1 - fraction_y
                    c1 = bTemp.GetPixel(floor_x, floor_y)
                    c2 = bTemp.GetPixel(ceil_x, floor_y)
                    c3 = bTemp.GetPixel(floor_x, ceil_y)
                    c4 = bTemp.GetPixel(ceil_x, ceil_y)
                    b1 = CType((one_minus_x * c1.B + fraction_x * c2.B), Byte)
                    b2 = CType((one_minus_x * c3.B + fraction_x * c4.B), Byte)
                    blue = CType(one_minus_y * CType(b1, Double) + fraction_y * CType(b2, Double), Byte)
                    b1 = CType((one_minus_x * c1.G + fraction_x * c2.G), Byte)
                    b2 = CType((one_minus_x * c3.G + fraction_x * c4.G), Byte)
                    green = CType(one_minus_y * CType(b1, Double) + fraction_y * CType(b2, Double), Byte)
                    b1 = CType((one_minus_x * c1.R + fraction_x * c2.R), Byte)
                    b2 = CType((one_minus_x * c3.R + fraction_x * c4.R), Byte)
                    red = CType(one_minus_y * CType(b1, Double) + fraction_y * CType(b2, Double), Byte)
                    b.SetPixel(x, y, System.Drawing.Color.FromArgb(255, red, green, blue))
                    y = y + 1
                End While
                x = x + 1
            End While
        Else
            Dim x As Integer = 0
            While x < b.Width
                Dim y As Integer = 0
                While y < b.Height
                    b.SetPixel(x, y, bTemp.GetPixel(CType((Math.Floor(x * nXFactor)), Integer), CType((Math.Floor(y * nYFactor)), Integer)))
                    y = y + 1
                End While
            x = x + 1
            End While
        End If
        Return b
    End Function
Avatar billede basementjack Nybegynder
17. november 2004 - 11:41 #11
cyberfessor - du skal jo lægge et svar.. Ellers kan jeg ikke acceptere.. :)
Avatar billede burningice Nybegynder
17. november 2004 - 12:04 #12
ja, sorry... den var vist gået forbi i farten.. :)

ang. dit problem med at billedfilen bliver låst, så kan jeg umiddelbart ikke hjælpe dig hvis du ikke kan få deres løsning til at virke, for det er den samme jeg bruger.
Avatar billede basementjack Nybegynder
17. november 2004 - 12:06 #13
Så må jeg bare prøve noget hårdere.. :p
Avatar billede nielsbrinch Nybegynder
17. november 2004 - 15:24 #14
Giver den resize et pænt billede eller ser det underligt hakket ud, ligesom hvis man downsizer et for stort billede med browseren?
Avatar billede basementjack Nybegynder
17. november 2004 - 15:27 #15
Jeg synz det bliver meget pænt.. I hvert fald så længe man bruger bBilinear = true.. Har ikke prøvet uden..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester