необходимо создать двухцветную картинку и нарисовать чтолибо на ней попиксельно.
делаю:
Bitmap img= new Bitmap(100,100,System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
//массив img.Pallete.Entries содержит 2 допустимых цвета.
Color clr=img.Palette.Entries[0];
img.SetPixel(50,50,clr); //тут падает: Invalid parametr used
такое наблюдается также при PixelFormat = Format4bppIndexed,Format8bppIndexed
как победить?
и еще как менять цвета в img.Pallete.Entries?
простое
img.Palette.Entries[0]=Color.Red;
не меняет цвета(проверил дебагером), но и не дает ошибки.
... << RSDN@Home 1.0 beta 7a >>
22.08.05 14:20: Перенесено модератором из '.NET' — AndrewVK
M>необходимо создать двухцветную картинку и нарисовать чтолибо на ней попиксельно.
У меня не получилось создать Graphics на основе indexed bitmap. Кажется, это не разрешается в GDI+.
Можно рисовать вручную, используя BitmapData. Мне этого хватило.
А с палитрами я так и не разобрался. Для true color можно использовать Graphics.DrawImage с параметрами. Там есть вариант с цветокоррекцией. Но это не палитра, а именно исправление данных битмапа.
Здравствуйте, mihailik, Вы писали:
M>>необходимо создать двухцветную картинку и нарисовать чтолибо на ней попиксельно.
M>У меня не получилось создать Graphics на основе indexed bitmap. Кажется, это не разрешается в GDI+.
так и есть, но я не создаю Graphics, я пользуюсь методом BitMap.SetPixel()
M>Можно рисовать вручную, используя BitmapData. Мне этого хватило.
пример можно? например мне надо создать картинку "шахматную доску" черно белую.
M>>Можно рисовать вручную, используя BitmapData. Мне этого хватило.
M>пример можно? например мне надо создать картинку "шахматную доску" черно белую.
Сейчас нет, из дома принесу завтра. Лень по второму разу то же самое сооружать.
Вообще, попробуй посмотри класс BitmapData, он кажется в System.Drawing.Imaging. Он позволяет прямой доступ к данным пикселей битмапа. Особенно удобно для 1bpp, тогда в голове пиксели легко подсчитываются
Вначале делаешь bitmap.LockBits, читаешь/пишешь BitmapData при помощи Marshal.Copy. Потом (желательно в try/finally) делаешь UnlockBits.
M>Вначале делаешь bitmap.LockBits, читаешь/пишешь BitmapData при помощи Marshal.Copy. Потом (желательно в try/finally) делаешь UnlockBits.
кое как получилось, хотя на пример все равно хочется взглянуть
но проблемма осталась. мне нужна была 2х цветная картинка чтобы сохранить его в gif c 2х цветной палитрой. он же не смотря на то что у меня двухцветный битмап сохраняет с палитрой 256.
M>кое как получилось, хотя на пример все равно хочется взглянуть
Из дома я забыл взять, так что сел и натворил заново.
M>но проблемма осталась. мне нужна была 2х цветная картинка чтобы сохранить его в gif c 2х цветной палитрой. он же не смотря на то что у меня двухцветный битмап сохраняет с палитрой 256.
Есть такое дело. В документации не описано, можно ли это победить. Возможно, при помощи дополнительных недокументированых атрибутов.
Например, длительность кванта времени для анимированного GIF не определяется готовым свойством. Но класс ImageAnimator и, с его помощью, PictureBox, грамотно и качественно отображают анимированные GIF'ы. Можешь посмотреть в исходниках ImageAnimator, они там через недокументированный номер читают дополнительные атрибуты Image.
Кажется, функция называется Image.GetPropertyItem. Но вряд ли тебе она поможет
А вот пример готовой программы, работа с BitmapData.
using System;
using System.Collections;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace BitmapDataSample
{
class Class1
{
static string[] strMap=new string[]
{
" ",
" **** ",
" ** ",
" ***** ",
" ** ** ",
" ** ** ",
" *** **"
};
[STAThread]
static void Main(string[] args)
{
// Преобразование строчного представления в битовое
// (я сделал не совсем верно по порядку битов —
// буква будет повёрнута вокруг вертикальной оси)
BitArray[] bitLines=new BitArray[strMap.Length];
for( int iRow=0; iRow<strMap.Length; iRow++ )
{
bitLines[iRow]=new BitArray(8);
for( int iBit=0; iBit<8; iBit++ )
{
bitLines[iRow][iBit]=
( strMap[iRow][iBit]==' ' );
}
}
// Заполнение битмапа
Bitmap bmp=new Bitmap(8,strMap.Length,PixelFormat.Format1bppIndexed);
BitmapData bmpData=bmp.LockBits(
new Rectangle(0,0,8,strMap.Length),
ImageLockMode.ReadWrite,
PixelFormat.Format1bppIndexed );
try
{
byte[] tmpArr=new byte[1];
for( int i=0; i<strMap.Length; i++ )
{
bitLines[i].CopyTo(tmpArr,0);
// расчёт адреса
IntPtr scanI=(IntPtr)(
bmpData.Scan0.ToInt64()+
bmpData.Stride*i );
// занесение
Marshal.Copy(
tmpArr, 0,
scanI, 1 );
}
}
finally
{
bmp.UnlockBits(bmpData);
}
// Отображние для людей
Form f=new Form();
PictureBox p=new PictureBox();
p.Image=bmp;
p.SizeMode=PictureBoxSizeMode.StretchImage;
f.Controls.Add(p);
f.ShowDialog();
}
}
}
Цитирую: " Но класс ImageAnimator и, с его помощью, PictureBox, грамотно и качественно отображают анимированные GIF'ы. Можешь посмотреть в исходниках ImageAnimator, они там через недокументированный номер читают дополнительные атрибуты Image."
Tak vot eto vot — nepravda. S animirovannimi gifami ne rabotaet picturebox. Vernee rabotaet noo kraine nekorrektno.