Подтвердить что ты не робот

Как заполнять окно изображения динамически

Недавно я начал изучать программирование на С#. Я пытаюсь создать GUI, используя приложение формы Windows. Мне нужно обновить бутылку с разными цветами на основе некоторых условий. Я получаю четыре показания датчиков с электронной платы, которые представляют собой температуру, давление, плотность, объем. Основываясь на этих значениях, мне нужно обновить бутылочку с картинками. Я разработал форму окна, как показано ниже. windows form Я создал четыре флажка для четырех показаний датчика. Внутри я вхожу в ожидаемый объем передачи вручную и устанавливаю это значение как максимальный масштаб на бутылке изображения. Для оценки того, какое количество существует в объеме, используются поля для измерения температуры, давления, плотности. Чтобы оценить количество в объеме, пользователь может использовать датчик температуры или датчик плотности или все из них или только два из них. Если я нажму одну кнопку, то я собираюсь использовать только этот датчик, читающий вот так. Флажок для объема означает получение объема объема, переданного до настоящего времени. У меня есть такие условия, чтобы оценить количество.

1)Liquid 
 Temperature = 0 to 30 c
 Pressure =    0 to 200 bar
 Density  = 0.5 to 0.95 g/cc.
2)Gas
 Temperature = 31 to 60 c
 Pressure =    201 to 400 bar
 Density  =    0 to 0.5 g/cc.
3)Water
 Temperature = 61 to 90 c
 Pressure =    401 to 600 bar
 Density  =    0.956 to 1,15 g/cc.
4)Oil
 Temperature = 91 to 120 c
 Pressure =    601 to 800 bar
 Density  =    1.2 to 1.35 g/cc.
5)Mud
 Temperature = 121 to 150 c
 Pressure =    801 to 1000 bar
 Density  =    1.15 to 1.3 g/cc.
6)Not identified
 all the conditions failed.

Процедура заключается в том, что если я поставлю флажки всех трех датчиков, тогда я собираюсь использовать три показания датчика и проверять эти условия и то, что когда-либо выполняется, и заполнять бутылку цветом. Я получу объем, сколько будет передано в настоящее время, и проверьте эти условия и заполните это количество в бутылке с цветом. У меня есть код для рисования рамки, когда я вводил значения вручную, но не хотел использовать значения и условия датчика.

    private void DrawPercentages(int[] percentages, Color[] colors, float[] volumetransfer)
    {
        Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        Graphics G = Graphics.FromImage(bmp);
        // Create a Graphics object to draw on the picturebox
        //Graphics G = pictureBox1.CreateGraphics();

        // Calculate the number of pixels per 1 percent
        float pixelsPerPercent = pictureBox1.Height / volumetransfer[0];

        // Keep track of the height at which to start drawing (starting from the bottom going up)
        int drawHeight = pictureBox1.Height;

        // Loop through all percentages and draw a rectangle for each
        for (int i = 0; i < percentages.Length; i++)
        {
            // Create a brush with the current color
            SolidBrush brush = new SolidBrush(colors[i]);
            // Update the height at which the next rectangle is drawn.
            drawHeight -= (int)(pixelsPerPercent * percentages[i]);
            // Draw a filled rectangle
            G.FillRectangle(brush, 0, drawHeight, pictureBox1.Width, pixelsPerPercent * percentages[i]);
        }
        pictureBox1.Image = bmp;
    }

Пожалуйста, помогите мне, как это сделать. У меня есть код для флажка, как показано ниже (для всех флажков).

 private void chkTransferTemp_CheckedChanged(object sender, EventArgs e)
    {
        if (chkTransferTemp.Checked)
        {
            Tempvalue = SystemNames.Temp.Data;
        }
    }

Пожалуйста, помогите мне с этой задачей.

Задача заключается в том, что я получу флажок объема из объема, поэтому мне нужно заполнить столько количества в бутылочке с картинками. общее количество представляет собой жидкость или газ или воду или какое-либо другое, принимая во внимание приведенные выше условия. Например, у меня есть "50" от датчика объема, тогда я должен обновить бутылку с изображением до 50 (по шкале) с цветом. в то же время цвет которого должен определяться вышеуказанными условиями. Я получаю температуру, давление, значения плотности, и мне нужно проверить, это "газ" или "жидкость" или "вода". и любое условие выполняется, затем заполняйте до масштаба "50" этим цветом.

Я пробовал вот так

        public void DrawVolume(double volume, VolumeTypes volumeType, PictureBox pictureBottle)
    {
        ucSample sample = new ucSample();

        Color color = pictureBottle.BackColor;

        switch (volumeType)
        {
            case VolumeTypes.Gas: color = Color.Lime;
                break;
            case VolumeTypes.HydrocarboneLiquid: color = Color.Red;
                break;
            case VolumeTypes.Water: color = Color.Blue;
                break;
            case VolumeTypes.WaterBasedMud: color = Color.SaddleBrown;
                break;
            case VolumeTypes.OliBasedMud: color = Color.Chocolate;
                break;
            case VolumeTypes.NotIdentified: color = Color.Gray;
                break;

        }
        Bitmap bmp = new Bitmap(pictureBottle.Width, pictureBottle.Height);
        Graphics G = Graphics.FromImage(bmp);

        float pixelsPerPercent = (float)(pictureBottle.Height * (volume / ucSample.Volume));

        int drawHeight = (int)volume;
        SolidBrush brush = new SolidBrush(color);
        G.FillRectangle(brush, 0, drawHeight, pictureBottle.Width, (int)(pixelsPerPercent * volume));
        pictureBottle.Image = bmp;

    }

То, что я пытаюсь из вышеприведенного кода, следующее: я передаю три аргумента методу "DrawVolume", аргумент "volume" - это значение, которое я хочу заполнить в окне изображения. "volumeType" - это цвет, относящийся к этому тому. Шкала "ucSample.Volume" окна изображения.

Приведенный выше код не работал, что я хочу. он не заполняется, как я хочу. например, у меня есть шкала от "0 до 100" для окна с картинкой, и у меня есть "объем" как "50" , тогда он должен рисовать от "0 до 50", но вышеприведенный код рисует больше, чем вокруг "от 0 до 60", Я не знаю, почему так происходит. Я использую неправильный расчет в "drawheight".

Под ред.

    public enum VolumeTypes { Water, Gas, HydrocarboneLiquid, OliBasedMud, WaterBasedMud, NotIdentified, None }
    public VolumeTypes GetVolumeType(double density, double temprature, double pressure)
    {
        bool isDensityChecked = true;
        bool isTempratureChecked = true;
        bool isPressureChecked = true;

        bool IsGasePhase = (isDensityChecked) ? (density >= 0 && density <= 0.4) : true && (isTempratureChecked) ? (temprature >= 0 && temprature <= 30) : true &&
            (isPressureChecked) ? (pressure >= 0 && pressure <= 100) : true;
        bool isHydrocarbanliquid = (isDensityChecked) ? (density >= 0.5 && density <= 1) : true && (isTempratureChecked) ? (temprature >= 31 && temprature <= 60) : true &&
           (isPressureChecked) ? (pressure >= 101 && pressure <= 200) : true;
        bool isWater = (isDensityChecked) ? (density >= 1 && density <= 2) : true && (isTempratureChecked) ? (temprature >= 61 && temprature <= 90) : true &&
           (isPressureChecked) ? (pressure >= 201 && pressure <= 300) : true;
        bool isWaterBasedMud = (isDensityChecked) ? (density >= 2.1 && density <= 3) : true && (isTempratureChecked) ? (temprature >= 91 && temprature <= 120) : true &&
           (isPressureChecked) ? (pressure >= 301 && pressure <= 400) : true;
        bool isOilBasedMud = (isDensityChecked) ? (density >= 3.1 && density <= 4) : true && (isTempratureChecked) ? (temprature >= 121 && temprature <= 150) : true &&
           (isPressureChecked) ? (pressure >= 401 && pressure <= 500) : true;
        bool isNotIdentified = (isDensityChecked) ? (density >= 4.1 && density <= 5) : true && (isTempratureChecked) ? (temprature >= 151 && temprature <= 200) : true &&
           (isPressureChecked) ? (pressure >= 501 && pressure <= 600) : true;

        VolumeTypes volumeType = VolumeTypes.None;

        if (IsGasePhase) volumeType = VolumeTypes.Gas;
        if (isHydrocarbanliquid) volumeType = VolumeTypes.HydrocarboneLiquid;
        if (isWater) volumeType = VolumeTypes.Water;
        if (isWaterBasedMud) volumeType = VolumeTypes.WaterBasedMud;
        if (isOilBasedMud) volumeType = VolumeTypes.OliBasedMud;
        if (isNotIdentified) volumeType = VolumeTypes.NotIdentified;

        return volumeType;


    }

    public void DrawVolume(double volume, VolumeTypes volumeType, PictureBox pictureBottle)
    {
        int x, y, width, height;
        x = 0;
        ucSample sample = new ucSample();


        y = (int)((1 - (volume / ucSample.Volume)) * pictureBottle.Height);
        // MessageBox.Show(ucSample.Volume +"");
        width = pictureBottle.Width;
        height = (int)((volume / ucSample.Volume) * pictureBottle.Height);

        Color color = pictureBottle.BackColor;

        switch (volumeType)
        {
            case VolumeTypes.Gas: color = Color.Lime;
                break;
            case VolumeTypes.HydrocarboneLiquid: color = Color.Red;
                break;
            case VolumeTypes.Water: color = Color.Blue;
                break;
            case VolumeTypes.WaterBasedMud: color = Color.SaddleBrown;
                break;
            case VolumeTypes.OliBasedMud: color = Color.Chocolate;
                break;
            case VolumeTypes.NotIdentified: color = Color.Gray;
                break;

        }
        Graphics graphics = pictureBottle.CreateGraphics();
        pictureBottle.Refresh();
        Rectangle rec = new Rectangle(x, y, width, height);
        graphics.FillRectangle(new SolidBrush(color), rec);

        //Bitmap bmp = new Bitmap(pictureBottle.Width, pictureBottle.Height);
        //Graphics G = Graphics.FromImage(bmp);

        //float pixelsPerPercent = (float)(pictureBottle.Height * (volume / ucSample.Volume));

        //int drawHeight = (int)volume;
        //SolidBrush brush = new SolidBrush(color);
        //G.FillRectangle(brush, 0, drawHeight, pictureBottle.Width, (int)(pixelsPerPercent * volume));
        //pictureBottle.Image = bmp;

    }


    private void UpdateTable(AnalogSensorData data)
    {
        DataRow row = _table.Rows.Find(_recs);
        if (row == null)
        {
            row = _table.NewRow();
            row["Index"] = _recs;
            row["DateTime"] = data.Time;
            row["Time"] = data.Time.ToLongTimeString();                
            row[data.SystemName] = data.Eng;

            _logs = 1;
            _table.Rows.Add(row);
        }
        else
        {
            row[data.SystemName] = data.Eng;
            if (++_logs >= SensorUC.NumberOfActive)
            {
                int i = 1;
                double density = 0, temprature = 0, pressure = 0, volume = 0;
                foreach (var item in row.ItemArray)
                {
                    sheet.Cells[(int)_recs + 3, i].Value = item;

                    //if (i == 4)
                    //{
                    //    object densityCell = item;
                    //    density = (densityCell != null) ? (double)densityCell : 0;
                    //    MessageBox.Show("density is : " + density + "");
                    //}
                    if (i == 8)
                    {
                        object pressureCell = item;
                        pressure = (pressureCell != null) ? (double)pressureCell : 0;
                        //MessageBox.Show("pressure is : " + pressure + "");
                    }
                    else if (i == 12)
                    {
                        object tempratureCell = item;
                        temprature = (tempratureCell != null) ? (double)tempratureCell : 0;
                       // MessageBox.Show("temprature is : "+ temprature + "");
                    }
                    if (i == 11)
                    {
                        object volumeCell = item;
                        volume = (volumeCell != null) ? (double)volumeCell : 0;
                        //MessageBox.Show("Volume is : "+ volume + "");
                    }

                    i++;

                }
              VolumeTypes volumeType = GetVolumeType(density, temprature, pressure);

              DrawVolume(volume, volumeType, pictureBottle);
                book.SaveAs(_logFile);
                _recs++;

            }
        }
        if (!_list.Columns[data.SystemName].HeaderText.Equals(data.SensorName))
        {
            _table.Columns[data.SystemName].Caption = data.SensorName;
            _list.Columns[data.SystemName].HeaderText = data.SensorName;
        }
        _list.FirstDisplayedCell = _list.Rows[_list.Rows.Count - 1].Cells[0];
        _list.Update();
    }

Концепция этой задачи в основном зависит от двух переменных 1) том: это оригинальный том, который мне нужно нарисовать в окне с изображением цвета, каждая величина имеет разные условия. Только одно условие будет удовлетворять за раз. 2) ucSample.Volume: это масштаб бутылки с картинками.

Я хочу реализовать это. Первоначально я установил некоторый оценочный объем передачи (я тот, кто помещает количество в датчик), тогда он будет назначаться как шкала изображения. это работает. Теперь я начну считывать данные с датчика. Я получаю значение "объем" от датчика. он будет увеличиваться с "0 до предполагаемого объема передачи (макс. шкала)". например: Я установил оценочный объем передачи около 500 мл. Тогда моя шкала шкалы изображения будет назначаться от "0 до 500". Тогда я начну отсчеты датчика, и я поставлю количество в датчик объема. Поэтому изначально я перенесу 100 мл воды. Таким образом, коробка с картинками должна заполняться цветом воды от шкалы от 0 до 100 мл в окне изображения. После этого я передам "масло" от "100 мл до 200 мл" , поэтому на этот раз условия будут разными, поэтому мне нужно заполнить таким образом "от 0 до 100 мл с водяным цветом и от 100 мл до 200 мл с масляным цветом" Мне нужно заполнить бутылочку с изображением на основе состояния и объема.

Из приведенного выше кода я могу заполнить бутылку с изображением только одного цвета. например, у меня есть вода от "0 до 100 мл", тогда я прекрасно заполняю бутылку с обратным цветом воды. затем от "100 мл до 200 мл" , затем заполняется масляной формой "0 до 200", а не "от 0 до 100 мл с акварельным цветом" и "100 мл до 200 мл" с масляным цветом.

Под ред. Я думаю, что многие пользователи неправильно понимают мою концепцию. Мне очень жаль, что плохое объяснение может быть из-за моего английского. Я попытался объяснить все, как показано ниже.

Я пытаюсь оценить входящую величину, поступающую из системы. Первоначально я установил, что ожидаемый объем количества будет прибывать (ucSample.Volume) из системы, это будет назначаться как шкала для pictureBox. Это прекрасно работает. У меня есть определенные условия для оценки входящего количества. У меня есть один датчик объема, который собирается указать, сколько количества уже поступило из системы (хранится в переменной "volume" ). Я обновляю окно изображения каждую секунду. Я назначил цвет для каждой величины.

например: Я установил оценочный объем "500" (ucSample.Volume = 500), затем я запустил систему. Система будет выливать жидкость медленно, она займет 30 монет для 100 мл количества. Когда система пропускает жидкость медленно в это время, я буду считывать плотность, давление, температуру этой жидкости с помощью датчиков и проверять, какое условие выполняется, в соответствии с условием, что он выберет один цвет. Поэтому у меня есть один датчик объема, который дает чтение объема, которое прошло через систему до сих пор. Он будет обновляться каждую секунду, например, до сих пор система пропускает только 10 мл жидкости. Таким образом, картинка должна обновлять только до 10 в масштабе с учетом цвета. Далее предположим, что от 10 мл до 20 мл поступающая жидкость изменилась, поэтому условия будут разными, поэтому теперь мне нужно заполнить pictureBox разным цветом от 10 мл до 20 мл. (не от 0 до 20 мл). Это должно быть так, не нужно менять цвет предыдущего, который находится от "0 до 10 мл", сохраняя тот же цвет и добавляя другой цвет от "10 до 20 мл". Таким образом, концепция заключается в том, что мне нужно сохранить предыдущую, как есть, и продолжать обновление с предыдущей конечной точки.
Таким образом, мы не знаем, что происходит от системы, поэтому, наконец, увидев pictureBox, мы должны оценить, сколько количества (всего) поступило из системы, а также индивидуальное количество каждого типа.
Вышеприведенный код не обновляется, как описано выше, он обновляется, как сначала он заполняется "зеленым" цветом от "0 до 100 мл", а если количество изменяется от 100 до 200, то оно заполняется другим цветом от "0 до 200" мл ". (не от" 100 до 200".) Я теряю предыдущую информацию, так что это совершенно неправильно. Мне нужно сохранить начальный цвет, поскольку он зависит от того, сколько он уже нарисовал до любых изменений в жидкости, тогда, если какие-либо изменения придут, он должен начинаться с этого момента.

Надеюсь, я дал более четкое объяснение. Пожалуйста, помогите мне, если кто-нибудь поймет мою концепцию.

Наконец, у меня есть ответ на этот вопрос, но у меня небольшая проблема. Я могу обновить pictureBox динамически на основе условий, используя приведенный ниже код.

 public void DrawVolume(double volume, VolumeTypes volumeType, PictureBox pictureBottle)
    {
        int x, y, width, height;
        x = 0;

        y = (int)((1 - (volume / ucSample.Volume)) * pictureBottle.Height) ;

        width = pictureBottle.Width;
        height = (int)((volume / ucSample.Volume) * pictureBottle.Height);

        Color color = pictureBottle.BackColor;

        switch (volumeType)
        {
            case VolumeTypes.Gas: color = Color.Lime;
                break;
            case VolumeTypes.HydrocarboneLiquid: color = Color.Red;
                break;
            case VolumeTypes.Water: color = Color.Blue;
                break;
            case VolumeTypes.WaterBasedMud: color = Color.SaddleBrown;
                break;
            case VolumeTypes.OliBasedMud: color = Color.Chocolate;
                break;
            case VolumeTypes.NotIdentified: color = Color.Gray;
                break;

        }

        int myCurrentHeight = height - lastHeight;
        if (color != currentColor)
        {  
            Rectangle rec = new Rectangle(x, y, width, myCurrentHeight);
            myRectangles.Add(new MyRectangle(rec,color));
            currentColor = color;
        }
        else 
        {
            Rectangle rec = new Rectangle(x,y,width,myCurrentHeight+myRectangles.Last<MyRectangle>().rectangle.Height);
            myRectangles.Last<MyRectangle>().rectangle = rec;
        }
        lastHeight = height;
        Bitmap bitmap = new Bitmap(Log.frmSample.PictureBottle.Width, Log.frmSample.PictureBottle.Height);
        Graphics graphics = Graphics.FromImage(bitmap);
        foreach (MyRectangle myRectangle in myRectangles)
        {
            graphics.FillRectangle(new SolidBrush(myRectangle.color), myRectangle.rectangle); 
        }
        Log.frmSample.PictureBottle.Image = bitmap;

    }

Приведенный выше код обновляет окно изображения, как показано ниже.

pictureboxupdating

то, что я хочу сделать сейчас, это "первоначально окно изображения заполняется зеленым цветом, и если цвет меняется, то следующий цвет заполняется в верхней части предыдущего цвета, как показано на рисунке выше. Теперь мне нужно, чтобы изменения цвета то текущий цвет должен быть заполнен нижней частью picturebottle, а предыдущий цвет должен двигаться вверх. Концепция заключается в том, что любое новое количество приходит тогда, оно должно снизу. Таким образом, наконец, первый обновленный цвет будет иметь верхнюю часть бутылки с картинками, а последний обновленный цвет должен быть в нижней части picturebottle.

Пожалуйста, помогите мне, как это сделать.

4b9b3361

Ответ 1

Для формы это просто, я бы просто использовал панели. Измените их BackColor, установите их позиции, ширину, высоту. Обновление при необходимости.

Ответ 2

Вместо использования окна с картинкой я бы рекомендовал переопределить событие OnPaint Panel и рисовать непосредственно на нем (имея в виду, что вам нужно будет установить DoubleBuffered в true для формы, чтобы избежать мерцания и в некоторых случаях вызвать Refresh() или Invalidate()).

Это не связано напрямую, но это может помочь вам выяснить часть рендеринга: GDI + Rendering Дайте мне знать, если у вас есть дополнительные вопросы.