Avatar billede curriculum Nybegynder
24. februar 2005 - 13:37 Der er 13 kommentarer og
1 løsning

Update Image i databasen

Jeg har en MS SQL tabel med et Image felt. Jeg vil have en funktion der kan hente Image feltet ud, siden resize billedet til ratio af 640 og siden update Image feltet med det resize'ede billede.
Avatar billede burningice Nybegynder
24. februar 2005 - 19:01 #1
hvor meget kendskab har du til henholdsvis

1) hente fra database
2) Manipulere billede med GDI+
3) gemme i database?

spørger bare da det kunne være det specielt var en enkelt ting i processen du havde problemer med.
Avatar billede snepnet Nybegynder
25. februar 2005 - 00:31 #2
hej curriculum - prøv at se om du kan få nedenstående til at funge med dit Image-felt.
(errorhandling, tilpasning til din tabel og datalag mv. skal du nok lige kaste et blik på ;o)

mvh

using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Data;
using System.Data.SqlClient;

namespace ResizeDbImage
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            int someImageId = 1;
            int sizeX = 200, sizeY = 400;

            ImageDal dal = new ImageDal();
            byte[] imagebytes = dal.GetImageBytes(someImageId);

            imagebytes = ResizeImage(imagebytes, sizeX, sizeY);

            Image img = Image.FromStream(new MemoryStream(imagebytes));
            img.Save(@"C:\TestFiles\ReducedImage.jpg");

            dal.UpdateImage(someImageId, imagebytes);
        }

        // til ændring af størrelsen på en billede
        public static byte[] ResizeImage(byte[] image, int width, int height)
        {
            System.Drawing.Bitmap bmpOut = null;

            Bitmap bmp = new Bitmap(new MemoryStream(image));
            bmpOut = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bmpOut);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.FillRectangle(Brushes.White, 0, 0, width, height);
            g.DrawImage(bmp, 0, 0, width, height);
            bmp.Dispose();

            MemoryStream ms = new MemoryStream();
            bmpOut.Save(ms, ImageFormat.Jpeg);
            byte[] result = ms.ToArray();
            ms.Close();

            return result;
        }
    }

    public class ImageDal
    {
        // du kan hente dine bytes sådan her :
        public byte[] GetImageBytes(int imageId)
        {
            SqlConnection connection = new SqlConnection("...");
            SqlCommand command = new SqlCommand("select data from [image] where imageid = @pImageId", connection);
   
            command.Parameters.Add(new SqlParameter("@pImageId", SqlDbType.Int, 4, "imageid"));
            command.Parameters["@pImageId"].Value = imageId;
       
            byte[] image = null;

            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);           
            if(reader.Read())
            {                                       
                image = new byte[Convert.ToInt32(reader.GetBytes(0, 0, null, 0, Int32.MaxValue))];
                reader.GetBytes(0, 0, image, 0, image.Length);
            }

            reader.Close();

            return image;
        }

        // eller et Image sådan her
        public Image GetImage(int imageId)
        {
            MemoryStream ms = new MemoryStream(GetImageBytes(imageId));
            Image img = Image.FromStream(ms);
            ms.Close();
            return img;
        }

        // og du kan lave en opdatering sådan her :
        public void UpdateImage(int imageId, byte[] image)
        {
            SqlConnection connection = new SqlConnection("data source=JPPR-A193;initial catalog=ElmerPhoto;password=sa;persist security info=True;user id=sa;packet size=4096");
            SqlCommand command = new SqlCommand("update [image] set data=@pImageData where ImageId=@pImageId", connection);
   
            command.Parameters.Add(new SqlParameter("@pImageData", SqlDbType.Image));
            command.Parameters["@pImageData"].Value = image;
           
            command.Parameters.Add(new SqlParameter("@pImageId", SqlDbType.Int, 4, "ImageId"));
            command.Parameters["@pImageId"].Value = imageId;
       
            connection.Open();
            command.ExecuteNonQuery();   
            connection.Close();
        }
    }
}
Avatar billede curriculum Nybegynder
25. februar 2005 - 12:42 #3
cyberfessor:
1) fint
2) fint
3) jeg er i tvivl på konverteringen til image bytes efter resize'ing

snepnet: jeg ser på dit forslag på mandag.
Avatar billede snepnet Nybegynder
25. februar 2005 - 13:12 #4
hej cyberfessor :o)
konverteringen er bare lavet for at holde samme type igennem det viste scenarie (byte[]).

vi skrives ved
/snep
cyberfessor : det er kun én enkelt linie du skal sætte ind i koden.... det har en ganske god effekt her.
Avatar billede curriculum Nybegynder
28. februar 2005 - 11:49 #5
jeg konverterer lige c sharp koden til vb
Avatar billede curriculum Nybegynder
28. februar 2005 - 13:09 #6
Hvordan konverter jeg memorystream'en tilbage til byte ??
Dim result As Byte = ms.ToArray()
Avatar billede snepnet Nybegynder
28. februar 2005 - 13:20 #7
hej igen :o)
vil tro at det er sådan her (er ikke lige den store vb-helt) :
Dim result As Byte() = ms.ToArray()
mvh
Avatar billede curriculum Nybegynder
28. februar 2005 - 13:40 #8
problemet er at vb.net compileren behandler Byte og Byte() forskelligt .. det viste jeg ikke :) så nu kommer jeg videre...
Avatar billede curriculum Nybegynder
28. februar 2005 - 14:00 #9
Nu får jeg en anden fejl... "Type 'Byte' has no constructors"

Dim image As Byte()

command.Connection.Open()
Dim reader As SqlDataReader= command.ExecuteReader(CommandBehavior.CloseConnection)       
If (reader.Read()) Then                                   
    image = New Byte(Convert.ToInt32(reader.GetBytes(0, 0, null, 0, Int32.MaxValue)))
    reader.GetBytes(0, 0, image, 0, image.Length)
End If
reader.Close()
Avatar billede snepnet Nybegynder
28. februar 2005 - 16:30 #10
tjah.... er som sagt ikke noget lys til vb, men det kan være det er noget i denne stil :

Dim image() As Byte

command.Connection.Open()
Dim reader As SqlDataReader= command.ExecuteReader(CommandBehavior.CloseConnection)       
If (reader.Read()) Then
    Dim length as Int =
    ReDim image( Convert.ToInt32(reader.GetBytes(0, 0, null, 0, Int32.MaxValue)) )
    image = reader.GetBytes(0, 0, image, 0, image.Length)
End If
reader.Close()

Mvh
Avatar billede snepnet Nybegynder
28. februar 2005 - 16:31 #11
Du kan jo lige få docs for den slags :

Visual Basic Language Concepts 

Declaring Array VariablesSee Also
Arrays Overview | Array Usage | Advanced Features of Arrays | Arrays of Arrays | Collections as an Alternative to Arrays | Object-Oriented Programming in Visual Basic | Dim Statement | Byte Data Type | New | Short Data Type | Long Data Type | Preserve | Array.GetUpperBound Method | ReDim Statement | New
Array variables are declared the same way as other variables, using the Dim statement. You follow the variable name with one or more pairs of parentheses to indicate that it is an array rather than a scalar (a variable containing a single value).

To declare a single-dimensional array variable

In your declaration, add one pair of parentheses after the variable name, as in the following example:
Dim MySingleArray() As Integer
To declare a multidimensional array variable

In your declaration, add one pair of parentheses after the variable name and place commas inside the parentheses to separate the dimensions, as in the following example:
Dim My4DArray(,,,) As Short  ' Four-dimensional array.
To declare a jagged array variable

In your declaration, add as many pairs of parentheses after the variable name as there are levels of nested arrays, as in the following example:
Dim MyJaggedArray()()() As Byte  ' Array of arrays of Byte arrays.
Initializing Arrays
You can initialize an array variable as part of its declaration. You can do one of the following in the declaration statement:

Specify the initial length of one or more of the dimensions in the parentheses following the variable name, without assigning an array object to the variable.
Assign an array object to the variable, using the New clause. When you use a New clause, you must follow it with braces ({}), even if they are empty.
Assign an array object to the variable and supply initial lengths in the New clause.
Assign an array object to the variable and supply initial element values in the New clause. You can supply both lengths and values in the same New clause.
If you specify dimension lengths in the parentheses following the variable name, you must use a subsequent assignment statement to assign an array object to the variable. The following sample declarations show valid and invalid syntax for a single-dimensional array variable:

Dim BA(2) As Byte  ' Currently contains Nothing (no object).
Dim BA(2) As Byte = New Byte()  ' INVALID (New after length specified).
Dim BA() As Byte = New Byte() {}  ' Empty Byte array object.
Dim BA() As Byte = New Byte()  ' INVALID (missing braces).
Dim BA() As Byte = New Byte(2)  ' INVALID (missing braces).
Dim BA() As Byte = New Byte() {0,1,2}  ' (0) through (2).
Dim BA() As Byte = New Byte(2) {0,1,2}  ' (0) through (2).
You can initialize a multidimensional array variable in a similar manner. The following sample declarations show a two-dimensional array variable being declared as an Short array with 2 rows and 2 columns.

Dim S2X2(1, 1) As Short  ' (0) through (1), (0) through (1).
Dim S2X2(1, 1) As Short = New Short(,)  ' INVALID (New after lengths).
Dim S2X2(,) As Short = New Short(,)  ' INVALID (missing braces).
Dim S2X2(,) As Short = New Short(1, 1)  ' INVALID (missing braces).
Dim S2X2(,) As Short = New Short(,) {}  ' Empty array object.
Dim S2X2(,) As Short = New Short(1, 1) {}  ' Elements have default value.
Dim S2X2(,) As Short = New Short(,) {{5, 6}, {7, 8}}  ' Four elements.
The first argument represents the rows; the second argument represents the columns. In the arrays in the preceding declarations, the index values for both the row and the column range from 0 through 1.

When you initialize a jagged array variable, you can specify the dimension lengths only for the top-level array. The following sample declarations show valid and invalid syntax for an array of arrays of Byte elements:

Dim JB(1)() As Byte  ' Array of two arrays of Byte elements.
Dim JB(1)(1) As Byte  ' INVALID (can only specify top-level size).
Dim JB(1)() As Byte = New Byte()()  ' INVALID (New after lengths).
Dim JB()() As Byte = {New Byte() {}, New Byte() {}}  ' Empty arrays.
Dim JB()() As Byte = {New Byte(1) {}, New Byte(1) {}}  ' Default values.
Dim JB()() As Byte = {New Byte() {5, 6}, New Byte() {7, 8}}
In the last of the preceding declarations, JB is initialized to two elements, JB(0) and JB(1), each of which is initialized to a two-element Byte array, the first with element values 5 and 6 and the second with elements 7 and 8.

Array Size Limits
The length of every dimension of an array is limited to the maximum value of a Long data type, which is (2 ^ 64) - 1. The total size limit of an array varies, based on your operating system and how much memory is available. Using an array that exceeds the amount of RAM available on your system is slower because the data must be read from and written to disk.

Note  Because arrays are objects in Visual Basic .NET, it is important to distinguish between an array object and an array variable. An array object, once created, does not change its size or rank. An array variable, however, can have a succession of different arrays assigned to it during its lifetime, and these can be of different sizes and ranks.
Resizing Arrays
You can resize an array at any time by assigning a different array object to the same array variable, using either ReDim or a standard assignment statement. The new array object can have different dimensions and even a different rank. This helps you manage memory efficiently. For example, you can use a large array for a short time and then ReDim it to a smaller size. This frees up memory you no longer need.

When you ReDim an array, its existing values are normally lost. However, you can retain them by including the Preserve keyword in the ReDim statement. For example, the following statement allocates a new array, initializes its elements from the corresponding elements of the existing MyArray, and assigns the new array to MyArray.

ReDim Preserve MyArray(10, 20)
In a multidimensional array, you can change only the last dimension when you use Preserve. If you attempt to change any of the other dimensions, a run-time error occurs. If you do not know the current size of a dimension, you can use the GetUpperBound method, which returns the highest subscript value for the dimension you specify.

In the following example, the first line is valid, but the second line is not, because it attempts to change the first of two dimensions.

ReDim Preserve Matrix(Matrix.GetUpperBound(0), Matrix.GetUpperBound(1) + 10)
ReDim Preserve Matrix(Matrix.GetUpperBound(0) + 10, Matrix.GetUpperBound(1))
See Also
Arrays Overview | Array Usage | Advanced Features of Arrays | Arrays of Arrays | Collections as an Alternative to Arrays | Object-Oriented Programming in Visual Basic | Dim Statement | Byte Data Type | New | Short Data Type | Long Data Type | Preserve | Array.GetUpperBound Method | ReDim Statement | New



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

Send feedback on this topic to Microsoft

© Microsoft Corporation. All rights reserved.
Avatar billede curriculum Nybegynder
28. februar 2005 - 19:41 #12
Sådan, nu fungerer det. 1000 tak for jhælpen snepnet.
Sådan ser VB versionen ud, den er testet og fungerer.

Function GetPropertiesForDBImage(ByVal ImageId As Integer, ByVal sizeX As Integer, ByVal sizeY As Integer)
    Dim dal As ImageDal = New ImageDal
    Dim imagebytes As Byte() = dal.GetImageBytes(ImageId)
   
    Dim TempWidth, TempHeight As Integer
    Dim ratio As Decimal
    TempWidth = sizeX
    TempHeight = sizeY
   
    If TempWidth > 640 Or Tempheight > 640 Then
        If TempWidth > TempHeight Then
            ratio = (640/TempWidth)
            TempWidth = TempWidth*ratio
            TempHeight = TempHeight*ratio
        Else
            ratio = (640/TempHeight)
            TempWidth = TempWidth*ratio
            TempHeight = TempHeight*ratio
        End If
    End If

    imagebytes = ResizeImage(imagebytes, TempWidth, TempHeight)
   
    Dim img As Drawing.Image = FromStream(New MemoryStream(imagebytes))
    Dim ms As New MemoryStream
    img.Save(ms, Imaging.ImageFormat.Jpeg)

    dal.UpdateImage(ImageId, imagebytes, TempWidth, TempHeight)
End Function
   
Public Function ResizeImage(ByVal image As Byte(), ByVal width As Integer, ByVal height As Integer) As Byte()
    Dim bmpOut AS System.Drawing.Bitmap

    Dim bmp As Bitmap = New Bitmap(New MemoryStream(image))
    bmpOut = New Bitmap(width, height)
   
    Dim g As Graphics = Graphics.FromImage(bmpOut)
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
    g.FillRectangle(Brushes.White, 0, 0, width, height)
    g.DrawImage(bmp, 0, 0, width, height)
    bmp.Dispose()

    Dim ms As MemoryStream = New MemoryStream()
    bmpOut.Save(ms, ImageFormat.Jpeg)
   
    Dim result As Byte() = ms.ToArray()
    ms.Close()

    Return result
End Function

Public Class ImageDal
    'du kan hente dine bytes sådan her :
    Public Function GetImageBytes(ByVal imageId As Integer) As Byte()
        Dim connection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("Conn"))
        Dim command As SqlCommand = New SqlCommand("SELECT PiDbPicture FROM PiDb WHERE PiDbMainIdNo = @sImageId", connection)

        command.Parameters.Add(New SqlParameter("@sImageId", SqlDbType.Int, 4, "PiDbMainIdNo"))
        command.Parameters("@sImageId").Value = imageId
   
        Dim image As Byte()

        command.Connection.Open()
        Dim reader As SqlDataReader = command.ExecuteReader(CommandBehavior.CloseConnection)       
        If (reader.Read()) Then                                   
            image = New Byte(Convert.ToInt64(reader.GetBytes(0, 0, image, 0, Int32.MaxValue))) {}
            reader.GetBytes(0, 0, image, 0, image.Length)
        End If
        reader.Close()

        Return image
    End Function

    'og du kan lave en opdatering sådan her :
    Public Sub UpdateImage(Byval ImageId As Integer, ByVal image As Byte(), ByVal iWidth As Integer, ByVal iHeight As Integer)
        Dim connection As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("Conn"))
        Dim command As SqlCommand = New SqlCommand("UPDATE PiDb SET PiDbPicture = @pImageData, PiDbPictureWidth = @pImageWidth, PiDbPictureHeigth = @pImageHeight WHERE PiDbMainIdNo = @pImageId", connection)

        command.Parameters.Add(New SqlParameter("@pImageData", SqlDbType.Image))
        command.Parameters("@pImageData").Value = image
       
        command.Parameters.Add(New SqlParameter("@pImageId", SqlDbType.Int, 4, "PiDbMainIdNo"))
        command.Parameters("@pImageId").Value = imageId
       
        command.Parameters.Add(New SqlParameter("@pImageWidth", SqlDbType.Int, 4, "PiDbPictureWidth"))
        command.Parameters("@pImageWidth").Value = iWidth
       
        command.Parameters.Add(New SqlParameter("@pImageHeight", SqlDbType.Int, 4, "PiDbPictureHeigth"))
        command.Parameters("@pImageHeight").Value = iHeight
   
        connection.Open()
        command.ExecuteNonQuery()
        connection.Close()
    End Sub
End Class
Avatar billede curriculum Nybegynder
28. februar 2005 - 19:41 #13
Send et svar snepnet....
Avatar billede snepnet Nybegynder
28. februar 2005 - 19:55 #14
alletiders :o)
et svar skal du få.
mvh
/snep
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