MVC4 EF5 Актуализиране на растерно изображение --запазване в db

След редакция трябва да актуализирам лентова диаграма, съхранена в db. Имам около 20 часа за разглеждане на примери, но просто ги сглобих. Моят клас

public class Task
{
    public int TaskID { get; set; }
    public DateTime? SStart { get; set; }
    public DateTime? SEnd { get; set; }
    public DateTime? SCert { get; set; }
    public byte? Taskimage { get; set; }
}

Моят контролер:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(Task task)
    {
        if (ModelState.IsValid)
        {   db.Entry(task).State = EntityState.Modified;
            db.SaveChanges();
            // now create a new graph using the returned viewbag data

            var Mytopleft = 0;
            var Mytext = "";
            Bitmap mybmp = new Bitmap(400, 20);
            Graphics g = Graphics.FromImage(mybmp);
            g.DrawRectangle(Pens.Black, 0, 0, 400, 20);
            SolidBrush b = new SolidBrush(Color.OldLace);
            g.FillRectangle(b, 0, 0, 400, 20);
            // draw comma-delimited elements in multiple colors
            string[] chunks = Mytext.Split(',');
            var brush = new SolidBrush(Color.Black);
            SolidBrush[] brushes = new SolidBrush[] 
                {   new SolidBrush(Color.OldLace),          //removed 3 other brushes for clarity
                 };
            int c = 0;
            var tasks = db.Tasks.Include(t => t.Builder).Include(t => t.Lot);
            foreach (var titem in tasks.ToList())
            {
                if (titem.SStart == null)
                { c = 0; }
                else if (titem.SStart != null && titem.SEnd == null)
                { c = 1; }                             //removed 3 other cases for clarity
                // create a new rectangle displaced by offset and with color
                g.FillRectangle(brushes[c], Mytopleft, 0, 10, 20);
                Mytopleft += 10;
            }                
                               //write to folder as a test   this works  Gif is arbitrary.
                              //can't use c:\\lot1.bmp   -- can't write to root dir
            mybmp.Save("C:\\temp\\lot1.gif", System.Drawing.Imaging.ImageFormat.Gif);

            MemoryStream ms = new MemoryStream();
            mybmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);

            db.SaveChanges();
}

Така че след промяна на дата, променям лентовата диаграма и актуализирам изображението на TaskImage, съхранено в db.

Създаването на mybmp работи и записва файл във временната папка като тест.

От дни се опитвам да разбера как да запазя mybmp в TaskImage. Мисля, че част от моето объркване е присвояването, в старите ми дни бих направил нещо като mybmp= toarry(System.Drawing.Imageing.ImageFormat.Gif). Не мисля, че това работи в MVC C#. Мисля, че изображението всъщност е в System.Drawing.Image, докато се създава и модифицира.

И така в общи линии: първо кодът MVC4 EF5
- запишете създаденото изображение в поток от памет????
- конвертирайте потока от памет в масив от байтове
- препратете байта[] към полето TaskImage
- кажете .Посочете, че имаме модификация....... db.Entry(task).State = EntityState.Modified;
- запазване на промените..презаписване на съществуващо изображение.... db.SaveChanges();

Мисля, че това е правилната логика. Правя пълно преначертаване, вместо да модифицирам съществуващото изображение, така че не е необходимо първо да го извличам. Между другото, след като накарам това да работи, ще променя кода, за да съхранява TaskImage в свързана таблица, а не в редактираната таблица тук. Не мисля, че това ще промени структурата на вашия отговор.

Има много примери за извличане и преминаване към преглед. Мисля, че мога да се справя с това.

Стъписан!! Благодаря


person user2887440    schedule 12.12.2013    source източник


Отговори (2)


Псевдокод:
- запазване на създаденото изображение в поток от памет????
- конвертиране на поток от памет в масив от байтове
- препратка към байта [] към полето TaskImage
- кажете на .State, че имаме модификация....... db.Entry(task).State = EntityState.Modified;
- запишете промените..презапишете съществуващото изображение.... db.SaveChanges();

Изглежда добре.

И така, защо кодът?

mybmp.Save("C:\\temp\\lot1.gif", System.Drawing.Imaging.ImageFormat.Gif);

        MemoryStream ms = new MemoryStream();
        mybmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);

Записвате ли във файл или EF таблица? Заглавието казва Запазване в Db.

Всъщност „проблемът или грешката“ не е толкова ясен.

Това наистина ли е въпрос. Как да конвертирате изображение в byteArray и обратно? Тъй като запазването и извличането на записи от DB, които имат поле от тип Byte [], не е проблемът, нали? Така че предполагам, че имате нужда от това

 public static byte[] ImageToByteArray(Image image)
    {
        var memoryStream = new MemoryStream();
        image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg); // consider format
        return memoryStream.ToArray();
    }

    public static Image ByteArrayToImage(byte[] byteArray)
    {
        var memoryStream = new MemoryStream(byteArray);
        Image image = Image.FromStream(memoryStream);
        return image;
    }

РЕДАКТИРАНЕ: public class Task { public int TaskID { get; комплект; } обществена дата и час? SStart { get; комплект; } обществена дата и час? SEnd { get; комплект; } обществена дата и час? SCert { get; комплект; } обществен байт? Taskimage { get; комплект; } // ‹‹‹‹‹‹ прави байтов масив ?????? } Моят контролер:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Task task)
{
    if (ModelState.IsValid)
    {   


        // 
        // now create a new graph using the returned viewbag data
      Image graph = CreateImageFromViewBag(viewbag); // refactored out... 
      task.Image =  ImageToByteArray(graph);

       db.Entry(task).State = EntityState.Modified;


        db.SaveChanges();

}

person phil soady    schedule 12.12.2013
comment
Виждал съм до и от, но не можах да разбера как да взема връщането и да го запиша в полето TaskImage в таблицата EF. - person user2887440; 12.12.2013
comment
Как да конвертирате принципите във вграден код. Това означава да вземете връщането и да го запишете в полето TaskImage в таблицата EF. Изглежда, че линията image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg) записва изображението в ms. ms.ToArray) го преобразува в байт []. Сега имам нужда от кода, за да присвоя .ToArray() на TaskImage. Тогава предполагам, че моят db.Entry.... ще актуализира записа.@philsoady - person user2887440; 12.12.2013
comment
Да, проблемът е как да стигнете от потока на паметта до db.save. Нещо като Task.TaskImage = ImageFromStream(ms.ToArray()); @фил - person user2887440; 12.12.2013

За да помогнете на другите тук има работещ код Както при много неща, след като го разберете, е доста просто, това работи. Това записване в свързана таблица, оттук и lottoupdate.

mybmp.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
        byte[] byteArray = new byte[0];
        ms.Close();
        var lottoupdate = db.Lots             //each task row contains the lotid to which
               .Where(i => i.LotID == lotID)  //it is associated. Find the LotID then
               .Single();                    // update the taskimage field in the lot class
         byteArray = ms.ToArray();
        lottoupdate.TaskImage = byteArray;
        db.Entry(lottoupdate).State = EntityState.Modified;
        db.SaveChanges();

Надявам се това да помогне на някой друг. За да извлечете това изображение и да го покажете в изгледа, вижте този въпрос: Изображение към байт[] по-трудно от мисленето 2 предизвикателства

person user2887440    schedule 22.12.2013