ketan Ram Patil Ответов: 2

Как обрезать изображение в WPF VB


я не могу обрезать изображение на контрольном изображении, пожалуйста, помогите.

когда я передаю холст x,y, высоту и ширину обрезки в функцию обрезки, он дает неправильное маленькое изображение обрезки


Заранее спасибо.

Что я уже пробовал:

    Public Function Crop(ByVal srcBitmap As Bitmap, _
ByVal cropX As Integer, ByVal cropY As Integer, ByVal cropWidth As Integer, ByVal cropHeight As Integer) As Bitmap

        ' Create the new bitmap and associated graphics object
        Dim bmp As New Bitmap(srcBitmap, cropHeight, cropWidth)

        Dim g As Graphics = Graphics.FromImage(bmp)

        Dim rect As Rectangle = New Rectangle(cropX, cropY, cropWidth, cropHeight)
        ' Draw the specified section of the source bitmap to the new one
        g.DrawImage(srcBitmap, New Rectangle(0, 0, cropHeight, cropWidth), rect, GraphicsUnit.Pixel)
        ' Clean up
        srcBitmap.Dispose()
        Return bmp



    End Function

Graeme_Grant

Вы используете старый GDI+ в приложении WPF. Почему?

ketan Ram Patil

Dim rect1 как новый Rect(Canvas.GetLeft (selectionRectangle), холст.GetTop(selectionRectangle), selectionRectangle.Ширина, selectionRectangle.Высота)
Dim rcFrom как новая система.Окна.Int32Rect()
rcFrom.Х = Кинт((rect1.Х) * (рис1.Источник.Ширина) / (image1.Ширина))
rcFrom.Г = Кинт((rect1.Г) * (рис1.Источник.Высота) / (изображение 1.Высота))
rcFrom.Width = CInt ((rect1.Ширина) * (изображение 1.Источник.Ширина) / (image1.Ширина))
rcFrom.Высота = CInt ((rect1.Высота) * (изображение 1.Источник.Высота) / (изображение 1.Высота))
'Дим Bitmapimage В Качестве Объекта Bitmapimage
'Объект bitmapimage = рис1.Источник
- Растровое изображение.Источник потока.Искать(0, Системы.ИО.SeekOrigin.Начать)
Dim bs As BitmapSource = New CroppedBitmap(TryCast(image1.Источник, BitmapSource), rcFrom)
Изображение 2.Источник = bs
Конец, Если


я тоже использую эту функцию, но она работает только для небольшого урожая.
для большого урожая это дает "значение не падает с ожидаемым диапазоном " :(

Graeme_Grant

Вы смотрели на ссылку ниже?

ketan Ram Patil

я свежее в wpf :(
куда отправить холст Х,Y,высота,ширина значения..?

Graeme_Grant

Прочтите Решение ниже-Microsoft дает вам рабочее решение.

ketan Ram Patil

я старался изо всех сил, но не могу сопоставить этот код в своем проекте. пожалуйста помочь

Graeme_Grant

Не используйте GDI+.

Вот код по ссылке ниже:

' Create an Image element.
Dim croppedImage As New Image()
croppedImage.Width = 200
croppedImage.Margin = New Thickness(5)

' Create a CroppedBitmap based off of a xaml defined resource.
Dim cb As New CroppedBitmap(CType(Me.Resources("masterImage"), BitmapSource), New Int32Rect(30, 20, 105, 50))
'select region rect
croppedImage.Source = cb 'set image source to cropped

Пожалуйста, найдите время, чтобы прочитать справку Microsoft.

ketan Ram Patil

да, это применимо для небольшого изображения, а не для большого изображения.. it croppedbitmap дает ошибку. "Значение не попадает в диапазон"

когда m передает значение my code Rect1

Dim bs As BitmapSource = New CroppedBitmap(TryCast(image1.Source, BitmapSource), New Int32Rect(rcFrom.X, rcFrom.Y, rcFrom.Ширина, rcFrom.Высота))

Graeme_Grant

Насколько велико изображение??

Graeme_Grant

Это может быть вашей проблемой... Существуют ограничения на то, насколько большими могут быть изображения... Прочтите об этом: Каково максимальное разрешение растрового изображения C# .NET? - переполнение стека[^] и c# - ограничение размера изображения BitmapImage - переполнение стека[^]

Graeme_Grant

Цитата: "размеры 1920 пикселей * 1280 пикселей, 72 dpi ,битовая глубина 24, 152 КБ в формате JPEG"

Это не должно быть проблемой...

ketan Ram Patil

он работает для = размеры 1920 пикселей * 1280 пикселей, 72 dpi ,битовая глубина 24, 152 КБ в формате JPEG

не могу работать для этого формиата изображения = размеры 2496 пикселей * 3504 пикселя, 300 точек на дюйм ,битовая глубина 24, 152 КБ в формате JPEG

Graeme_Grant

Какой метод вы используете и что такое сообщение об ошибке?

ketan Ram Patil

https://stackoverflow.com/questions/39261580/image-cropping-in-c-values-does-not-fall-in-expected-range

та же проблема....

Graeme_Grant

Ладно, я знаю, что ваша проблема, скорее всего, будет... ошибка расчета. Ниже я опубликую новое решение с рабочим кодом...

Graeme_Grant

Как вы поступили с решением 2 ниже?

Graeme_Grant

Что все это значит? Мое решение помогло вам заставить его работать???

ketan Ram Patil

спасибо за код. код отлично работает для 96 точек на дюйм, но
для 300 точек на дюйм дает "значение не попадает в ожидаемый диапазон"

Graeme_Grant

разместите изображение с разрешением 300 точек на дюйм где-нибудь и поделитесь url-адресом.Я посмотрю на него поближе.

ketan Ram Patil

извините за поздний ответ . https://drive.google.com/file/d/0B0Hbd1jJiwLFN3VtTUY1Nl9rUFk/view

Graeme_Grant

Все благо. Странно, что это сработало для исходного большого тестового изображения... Наверное, мне просто повезло!

Новое изображение показывало, что расчет масштаба вышел из строя и захватил неправильную часть изображения выше. Как только я перешел на пиксели для CroppedBitmap(xxx) в Go_Click метод, позиционирование было зафиксировано! Смотрите обновленное Решение 2[^] ниже...

ketan Ram Patil

Ты великий... < 3 < 3
Спасибо:) за ваш ценный ответ..:)

n еще раз спасибо...... это работает отлично.

Graeme_Grant

Добро пожаловать! :)

Graeme_Grant

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

ketan Ram Patil

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

Graeme_Grant

К сожалению, не понимая.

ketan Ram Patil

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

Graeme_Grant

Все еще не понимая... Он уже делает это...

Когда вы ответите на этот вопрос, пожалуйста, начните новый вопрос.

ketan Ram Patil

вы видели программное обеспечение принтеров hp? после сканирования изображения они обеспечивают функциональность обрезки, я хочу сделать ту же функциональность обрезки ... я хочу предоставить прямоугольник обрезки на изображении. :(

Graeme_Grant

Вы хотите изменить размер прямоугольника выделения, а не рисовать новый? Это выходит за рамки данного вопроса. Вам нужно исследовать рукоятки захвата, которые можно перетаскивать.

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

ketan Ram Patil

да, я хочу изменить размер прямоугольника выделения, чтобы не рисовать новый. хорошо.. я буду искать на ручках захвата спасибо за ваш ценный повтор.. :)

ketan Ram Patil

еще раз спасибо за ручкой слова и помогли мне найти мою проблему наконец-то я нашел решение. спасибо еще раз..
вы-gr8... :)

ketan Ram Patil

я хочу задать тебе вопрос. Как удалось подсчитать перейдите. Математика урожая.
какую статью мне нужно прочитать для изучения.

Graeme_Grant

Никакого сайта... Я использовал электронную таблицу excel и разработал ее сам.

ketan Ram Patil

ОК .. :) gr8...
я не решаюсь вам сказать.
то же самое снова значение дозы не упадет с в ожидаемом диапазоне проблемы случаются и со мной... :(
с новым проектом изменения размера прямоугольника.

shubh2895

спасибо за код обрезки ... он работает....

пожалуйста помочь

я застрял на проблеме яркости изображения в wpf с помощью ползунка управления.

я попытался передать значения этой функции, но она выдает ошибку

"ссылка на объект не установлена на экземпляр объекта"
Общие функции яркости(изображения бывал как растровое изображение, SliderValue бывал как целое) Как Растровое Изображение

'DrawImage(изображение, GetBrightnessMatrix (процент))

Dim brtR As Single = CSng(SliderValue / 100)
Dim brtG As Single = CSng(SliderValue / 100)
Dim brtB As Single = CSng(SliderValue / 100)
Dim image_attr как новые атрибуты ImageAttributes
Дим см в подразделениях компании = Новый подразделениях компании(новый сингл()() _
{ _
New Single () {brtR, 0.0, 0.0, 0.0, 0.0}, _
New Single () {0.0, brtG, 0.0, 0.0, 0.0}, _
New Single () {0.0, 0.0, brtB, 0.0, 0.0}, _
Новый Сингл() {0.0, 0.0, 0.0, 1.0, 0.0}, _
Новый Сингл() {0.0, 0.0, 0.0, 0.0, 1.0}})

Тусклый прямоугольник как прямоугольник = _
Прямоугольник.Круглые(рис.Метод Getbounds(GraphicsUnit.Пиксель))
Дим ужр как целое число, = изображения.Ширина
Dim hgt как целое число = изображение.Высота

Дим img В качестве нового растрового изображения(ужр, хагат)
Dim gr As Graphics = графика.FromImage(img)

image_attr.SetColorMatrix (см)
гр.Функция drawImage(изображения, прямоугольник, 0, 0, ужр, _
хагат, GraphicsUnit.Пиксель, image_attr)

Возврат img


Конечная Функция


Private Sub SliderBrightness_ValueChanged(ByVal sender As System.Объект, бывал е как система.Окна.RoutedPropertyChangedEventArgs(Of System.Двойной)) Ручки SliderBrightness.ValueChanged

Если образ1.Источник Ничего Не Значит


Dim i как целое число
i = Слайдербрайтность.Ценность
StackPanelImage.Source = ToBitmapImage (яркость (bitmapimage, i))
Конец, Если
Конец Подводной Лодки

2 Ответов

Рейтинг:
14

Graeme_Grant

У Microsoft WPF documents есть отличный пример для вас: Как обрезать изображение / Microsoft Docs[^]


Рейтинг:
12

Graeme_Grant

Итак, похоже, что у вас есть ошибка расчета - одно из значений может быть двойной.НАНА[^].

Этот код имеет ту же проблему и не был подхвачен теми, кто ответил: c# - обрезка изображения с помощью прямоугольника холста - переполнение стека[^]

Проблема заключается в этих расчетах:

rcFrom.X = (int)((rect1.X) * (image1.Source.Width) /(image1.Width));
rcFrom.Y = (int)((rect1.Y) *(image1.Source.Height) / (image1.Height));
rcFrom.Width = (int)((rect1.Width) * (image1.Source.Width) /(image1.Width));
rcFrom.Height = (int)((rect1.Height) * (image1.Source.Height) /(image1.Height));

Тестирование и отладка показали, что image1.Height и image1.Width возвращаемся double.NAN свойства. То, что они должны использовать, это image1.ActualHeight и Actualimage1.Width свойства.

Вот исправленная рабочая версия кода (ссылка выше в этом решении), работающая с размером изображения 3840 x 2160 jpeg:

XAML MainWindow:
<Window

    x:Class="WpfCropImage.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"



    mc:Ignorable="d"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"



    Title="CodeProject Answer - WPF Scale & Crop Images"

    Height="600" Width="1200" WindowStartupLocation="CenterScreen">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Grid x:Name="Gridimage1">
            <Image Name="image1" Stretch="Uniform"

                   Source="http://eskipaper.com/images/cool-morning-fog-wallpaper-1.jpg"/>
            <Canvas  x:Name="BackPanel" 

                     Height="{Binding ElementName=image1, Path=ActualHeight}"

                     Width="{Binding ElementName=image1, Path=ActualWidth}">
                <Rectangle x:Name="selectionRectangle" 

                           Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
            </Canvas>
        </Grid>
        <Button Content=">>" Grid.Column="1" Name="Go" 

                Click="Go_Click" FontWeight="Bold" 

                VerticalAlignment="Center" Margin="10"/>

        <Image Grid.Column="2" Name="image2" Stretch="Uniform" />

    </Grid>
</Window>

И код MainWindow-позади:
Обновление 16 августа 2017 года: Новый образец изображения показал, что вычисление масштабирования было неверным. Ниже код имеет коррекцию.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;

namespace WpfCropImage
{
    public partial class MainWindow : Window
    {
        private bool isDragging;
        private Point anchorPoint = new Point();

        public MainWindow()
        {
            InitializeComponent();

            Gridimage1.MouseLeftButtonDown += new MouseButtonEventHandler(image1_MouseLeftButtonDown);
            Gridimage1.MouseMove += new MouseEventHandler(image1_MouseMove);
            Gridimage1.MouseLeftButtonUp += new MouseButtonEventHandler(image1_MouseLeftButtonUp);

            Go.IsEnabled = false;
            image2.Source = null;
        }

        private void Go_Click(object sender, RoutedEventArgs e)
        {
            if (image1.Source != null)
            {
                var rect1 = new Rect()
                {
                    X = Canvas.GetLeft(selectionRectangle),
                    Y = Canvas.GetTop(selectionRectangle),
                    Width = selectionRectangle.Width,
                    Height = selectionRectangle.Height
                };

                // calc scale in PIXEls for CroppedBitmap...
                var img = image1.Source as BitmapSource;
                var scaleWidth = (img.PixelWidth) / (image1.ActualWidth);
                var scaleHeight = (img.PixelHeight) / (image1.ActualHeight);

                var rcFrom = new Int32Rect()
                {
                    X = (int)(rect1.X * scaleWidth),
                    Y = (int)(rect1.Y * scaleHeight),
                    Width = (int)(rect1.Width * scaleWidth),
                    Height = (int)(rect1.Height * scaleHeight)
                };

                image2.Source = new CroppedBitmap(inputImage, rcFrom);
            }
        }
        #region "Mouse events"

        private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!isDragging)
            {
                anchorPoint.X = e.GetPosition(BackPanel).X;
                anchorPoint.Y = e.GetPosition(BackPanel).Y;
                isDragging = true;
            }

        }

        private void image1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                double x = e.GetPosition(BackPanel).X;
                double y = e.GetPosition(BackPanel).Y;
                selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
                selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
                selectionRectangle.Width = Math.Abs(x - anchorPoint.X);
                selectionRectangle.Height = Math.Abs(y - anchorPoint.Y);

                if (selectionRectangle.Visibility != Visibility.Visible)
                    selectionRectangle.Visibility = Visibility.Visible;
            }
        }

        private void image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (isDragging)
            {
                isDragging = false;
                if (selectionRectangle.Width > 0)
                {
                    Go.Visibility = Visibility.Visible;
                    Go.IsEnabled = true;
                }
                if (selectionRectangle.Visibility != Visibility.Visible)
                    selectionRectangle.Visibility = Visibility.Visible;
            }
        }

        private void RestRect()
        {
            selectionRectangle.Visibility = Visibility.Collapsed;
            isDragging = false;
        }

        #endregion
    }
}