2017-02-18 4 views
1

Я пытаюсь нарисовать диагональную тень.Диагональная тень с GDI +

Сначала я делаю все пиксель черными:

Следующим с простым для такта это является результатом

Теперь я хочу, чтобы растянуть это изображение по диагонали имитировать тень.
Я пробовал:

Bitmap b = new Bitmap(tImage.Width + 100, tImage.Height); 
Graphics p = Graphics.FromImage(b); 
p.RotateTransform(30f); 
p.TranslateTransform(100f, -200f); 
p.DrawImage(tImage, new Rectangle(0, -20, b.Width+20, b.Height)); 

но изображения поворачиваются и переводил.

Пожалуйста, кто-нибудь есть решение для меня?

мне нужно, чтобы выглядеть следующим образом (создано в Photoshop):

+1

Вы пробовали [перекос?] (Https://msdn.microsoft.com/en-us/library/3b575a03 (v = vs.110) .aspx) - Примечание. что это все еще строго 2d! – TaW

+0

О, нет, это новое для меня. Я пытаюсь –

+0

Я пытаюсь, но я вижу изображение перевернутое или очень маленькое. Пример? –

ответ

2

Создание хороший DropShadow довольно задача, используя Winforms и GDI +.

В нем нет ни полигонального масштабирования, ни размытия; и давайте даже не подумаем о 3D ..! - Но мы можем, по крайней мере, сделать несколько вещей без особых усилий и получить хороший результат для многих изображений.

Предположим, у вас уже есть изображение, вырезанное из его фона.

Следующим шагом было бы превратить все цвета в черный.

Тогда мы, скорее всего, захотим добавить некоторый уровень прозрачности, так что фон, на который падает тень, все еще светит.

Обе задачи выполнены достаточно эффективно, используя подходящий ColorMatrix.

С очень прозрачной версией мы также можем создать простое размытие путем рисования изображения с помощью смещений. Для достижения наилучших результатов, я хотел бы обратить его в девять раз с 3 Дифференц веса/значения альфа ..

Высокое качество размывания это искусство, как вы можете видеть, даже просто глядя на фильтры и корректировки в профессиональном программном обеспечении, как Adobe Photoshop или Affinity Photo. Вот nice набор интересных ссылок ..

Но поскольку мы имеем дело только с растровым изображением ab/w, то оценка simpleitstic достаточно хороша. Я использую 3 альфа-значения 5%, 10% и 20% для 4 угол, 4 края и 1 центральные чертежи.

Последний шаг рисует тень с некоторым перекос.

Об этом сообщается here; но в то время как это, казалось бы, очень просто, это также несколько непрактично. Три точки, на которые рассчитывается оверлей DrawImage, должны быть рассчитаны.

Итак, вот метод, который делает именно это; обратите внимание, что это сильно упрощенный метод:

Оверлей занимает три очка, то есть плавает. Мы используем только номера:

  • один на сумму перекоса; 0.5 означает, что верхняя часть сдвигается вправо на половину ширины растрового изображения.
  • другие два являются масштабированием полученного ограничивающего прямоугольника. 1 и 0.5 означают, что ширина не изменяется и высота уменьшается до 50%.

Вот функция:

public Bitmap SkewBitmap(Bitmap inMap, float skewX, float ratioX, float ratioY) 
{ 
    int nWidth = (int)(inMap.Width * (skewX + ratioX)); 
    int nHeight = (int)(Math.Max(inMap.Height, inMap.Height * ratioY)); 
    int yOffset = inMap.Height - nHeight; 

    Bitmap outMap = new Bitmap(nWidth, nHeight); 

    Point[] destinationPoints = { 
     new Point((int)(inMap.Width * skewX), (int)(inMap.Height * ratioY) + yOffset), 
     new Point((int)(inMap.Width * skewX + inMap.Width * ratioX), 
        (int)(inMap.Height * ratioY) + yOffset), 
     new Point(0, inMap.Height + yOffset) }; 

     using (Graphics g = Graphics.FromImage(outMap)) 
     g.DrawImage(inMap, destinationPoints); 

    return outMap; 
} 

Примечание несколько упрощений:

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

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

  • Если Вы задаетесь вопросом, где информация из шести цифр идут, вот полный макет:

    • 3 идут в наши параметры
    • 1 будет угол поворота мы не делаем
    • 2 может быть либо центральную точку поворота или точку (DeltaX & у), по которому результат переводится
  • Если присмотреться у ou может видеть, что тень левой ноги немного ниже стопы. Это связано с тем, что ноги не находятся на одном уровне, а при вертикальном сжатии базовые линии дрейфуют друг от друга. Чтобы исправить это, мы либо изменим изображение, либо добавим крошечный поворот.

  • Глядя на образец вашего примера, ясно, что вы понесете его, чтобы разобрать его и обрабатывать «дом» и «дерево» отдельно!

  • Подпись проста в использовании; это всегда баланс между простотой использования и усилием в кодировании. On может пожелать, чтобы параметр дал угол для управления перекосом. Не стесняйтесь, чтобы выработать необходимые расчеты ..

enter image description here

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

Вот код в кнопку «перекоса»:

Bitmap bmp = SkewBitmap((Bitmap)pictureBox4.Image, 0.5f, 1f, 0.5f); 

pictureBox5.Image = pictureBox1.Image; 
pictureBox5.BackgroundImage = bmp; 
pictureBox5.ClientSize = new Size(bmp.Width, bmp.Height); 

Вместо того чтобы рисовать объект над тенью я использую дополнительный слой PictureBox. Вы бы, конечно, объединили два Bitmaps.

+0

Танки Taw! Ты обалденный. танков для вашей помощи! –