Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2015, 17:57   #1
BOZKURT
Пользователь
 
Регистрация: 14.10.2009
Сообщений: 70
По умолчанию WinForm: Отрисовка круглого аватара с заливкой тени внутрь

Всем привет!

Что-то никак не вкурю, помогите плиз нарисовать в PictureBox`е такую штуку, как во вложении.
Т.е., есть фото пользователя (квадратное), нужно его вывести в PictureBox (можно и в Bitmap/Image конечно) в виде круга, затем нарисовать круглую рамку вокруг фото и внутрь залить чуток тени (по краям).

Как нарисовать круг, вроде нашел:

Код:
public Image DrawAvatar(Image startImage, int radius, Color backgroundColor)
{
    radius *= 2;
    Bitmap RoundedImage = new Bitmap(startImage.Width, startImage.Height);
    using (Graphics g = Graphics.FromImage(RoundedImage))
    {
        g.Clear(backgroundColor);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        using (Brush brush = new TextureBrush(startImage))
        {
            using (GraphicsPath gp = new GraphicsPath())
            {
                gp.AddArc(2, 2, radius, radius, 180, 90);
                gp.AddArc(RoundedImage.Width - radius - 0, 2, radius, radius, 270, 90);
                gp.AddArc(0 + RoundedImage.Width - radius, 0 + RoundedImage.Height - radius, radius, radius, 0, 90);
                gp.AddArc(2, RoundedImage.Height - radius, radius, radius, 90, 90);

                g.FillPath(brush, gp);
            }
        }
        return RoundedImage;
    }
}
Изображения
Тип файла: png UserPhoto.png (7.9 Кб, 111 просмотров)
BOZKURT вне форума Ответить с цитированием
Старый 01.03.2015, 21:08   #2
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

А как насчет заготовить png с прозрачной круглой областью в центре и отрисовать его поверх фотографии? ИМХО вы потратите уйму времени на рисование этого руками: в результате вряд ли получится красиво, а малейшее изменение дизайна потребует изменения кода (причем нетривиального).
Изобретатель велосипедов
Selestis вне форума Ответить с цитированием
Старый 02.03.2015, 07:24   #3
BOZKURT
Пользователь
 
Регистрация: 14.10.2009
Сообщений: 70
По умолчанию

Да, эта мысль была первой, но вот захотелось сделать все "руками", т.к. не хочется зависеть от заготовок..
BOZKURT вне форума Ответить с цитированием
Старый 02.03.2015, 10:49   #4
Hollander
Участник клуба
 
Аватар для Hollander
 
Регистрация: 03.05.2007
Сообщений: 1,189
По умолчанию

Как вариант, можно сразу загружать фото пользователя и рисовать по нему:
Код:
public Image DrawAvatar(Image startImage, int radius, Color backgroundColor)
{
...
Bitmap bitmap = new Bitmap("user.jpg");
...
Hollander вне форума Ответить с цитированием
Старый 02.03.2015, 12:39   #5
KilljoySteklo
 
Регистрация: 28.02.2015
Сообщений: 3
По умолчанию

А если текстура в формате .dds DXT5 с альфа-каналом? Есть же наверно библиотеки для отрисовки такого?
KilljoySteklo вне форума Ответить с цитированием
Старый 02.03.2015, 13:04   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Первая ссылка в гугле http://stackoverflow.com/questions/8...o-a-picturebox
Я правда не понял зачем вы со своим dds влезли в эту тему.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 02.03.2015, 13:25   #7
BOZKURT
Пользователь
 
Регистрация: 14.10.2009
Сообщений: 70
По умолчанию

Всем спасибо, все сделал, да здравствует гугл! )

Код:
public static Image DrawAvatar(Rectangle bounds, Bitmap userPhoto, int roundRadius, Color shadowColor, Color transparentColor)
{
    Bitmap image = new Bitmap(bounds.Width, bounds.Height);
    using (Graphics g = Graphics.FromImage(image))
    {
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        //Изменяем размер под нужный
        userPhoto = new Bitmap(userPhoto, bounds.Width, bounds.Height);
        //Обрезаем фото
        g.DrawImage(CropRoundImage(bounds, userPhoto, bounds.Width / 2, Color.Transparent), 0, 0);
        using (GraphicsPath gp = new GraphicsPath())
        {
            gp.AddEllipse(bounds);
            using (PathGradientBrush pgb = new PathGradientBrush(gp))
            {
                pgb.CenterPoint = new PointF(bounds.Width / 2, bounds.Height / 2);
                pgb.CenterColor = transparentColor;
                pgb.SurroundColors = new Color[] { shadowColor };
                pgb.FocusScales = new PointF(0.8f, 0.8f); //начало перехода градиента (ширина градиента)

                g.FillPath(pgb, gp);
            }
        }
    }
    return image;
}

public static Image CropRoundImage(Rectangle bounds, Image startImage, int radius, Color backgroundColor)
{
    radius *= 2;
    Bitmap roundedImage = new Bitmap(bounds.Width, bounds.Height);
    using (Graphics g = Graphics.FromImage(roundedImage))
    {
        g.Clear(backgroundColor);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        using (Brush brush = new TextureBrush(startImage))
        {
            using (GraphicsPath gp = new GraphicsPath())
            {
                gp.AddArc(0, 0, radius, radius, 180, 90);
                gp.AddArc(bounds.Width - radius - 0, 0, radius, radius, 270, 90);
                gp.AddArc(0 + bounds.Width - radius, 0 + bounds.Height - radius, radius, radius, 0, 90);
                gp.AddArc(0, bounds.Height - radius, radius, radius, 90, 90);

                g.FillPath(brush, gp);
            }
        }
        return roundedImage;
    }
}
[Обновлено]
Используем так:
Код:
Rectangle bounds = new Rectangle(0, 0, Properties.Resources.default_avatar.Width, Properties.Resources.default_avatar.Height);
pictureBox1.Width = bounds.Width + 10;
pictureBox1.Height = bounds.Height + 10;

//Фото пользователя
Bitmap userImage = ImageHelper.DrawAvatar(bounds, Properties.Resources.default_avatar, bounds.Width / 2, Color.FromArgb(200, 200, 200), Color.Transparent);

//Тень под фото
Bitmap shadowImage = new Bitmap(bounds.Width + 10, bounds.Height + 10);
bounds = new Rectangle(0, 0, shadowImage.Width, shadowImage.Height);
shadowImage = ImageHelper.DrawAvatar(bounds, shadowImage, shadowImage.Width / 2, Color.Transparent, Color.FromArgb(220, 220, 220));

//Результирующее изображение
Bitmap resultImage = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using (Graphics g = Graphics.FromImage(resultImage))
{
    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.DrawImage(shadowImage, 0, 0);
    g.DrawImage(userImage, 5, 5);
    //Рамка
    Pen pen = new Pen(Color.White, 2f);
    g.DrawEllipse(pen, new Rectangle(6, 6, bounds.Width - 12, bounds.Height - 12));
}
pictureBox1.Image = resultImage;
Результат во вложении.
Изображения
Тип файла: png Avatar.png (4.2 Кб, 104 просмотров)
Тип файла: png default_avatar.png (2.2 Кб, 103 просмотров)
Тип файла: png Avatar2.png (6.4 Кб, 106 просмотров)

Последний раз редактировалось BOZKURT; 02.03.2015 в 18:39.
BOZKURT вне форума Ответить с цитированием
Старый 03.03.2015, 11:06   #8
KilljoySteklo
 
Регистрация: 28.02.2015
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Я правда не понял зачем вы со своим dds влезли в эту тему.
Потому что рисовать руками неправильно.
KilljoySteklo вне форума Ответить с цитированием
Старый 03.03.2015, 11:46   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от KilljoySteklo Посмотреть сообщение
Потому что рисовать руками неправильно.
Не могу понять, DDS какое отношение имеет к круглому аватару?!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 04.03.2015, 01:30   #10
KilljoySteklo
 
Регистрация: 28.02.2015
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Не могу понять, DDS какое отношение имеет к круглому аватару?!
С помощью альфа-канала можно добиться эффекта который здесь был нужен.
KilljoySteklo вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Добавление формы для загрузки аватара в базу Programmer_St PHP 1 07.10.2012 23:03
OpenGL. Проекционные тени и их отрисовка на плоскости стен комнаты capta1n Помощь студентам 1 07.12.2011 19:48
Баг при обрезке аватара fastjust Помощь студентам 1 03.09.2011 12:19
Проблема с заливкой в С. Salvadore Общие вопросы C/C++ 2 08.04.2010 13:23
Ошибка в создании круглого градиента. Alex Cones Общие вопросы Delphi 3 03.01.2010 16:28