سلام
من یه برنامه نوشیتم شبیه پینت و می خوام نقاشی که میکشن تو دیتا بیس ذخیره بشه ولی هر دفه فقط اگه عکس وارد پیچرباکس کنم فقط عکس ذخیره میشه تو دیتا بیس ولی نقاشیی که کشیده میشه اصلا تو دیتابیس ذخیره نمی شه راه حل شما چیه>؟؟؟
سلام
من یه برنامه نوشیتم شبیه پینت و می خوام نقاشی که میکشن تو دیتا بیس ذخیره بشه ولی هر دفه فقط اگه عکس وارد پیچرباکس کنم فقط عکس ذخیره میشه تو دیتا بیس ولی نقاشیی که کشیده میشه اصلا تو دیتابیس ذخیره نمی شه راه حل شما چیه>؟؟؟
سلام
فکر کنم باید یک شیء از نوع Image بسازید و در انتها شیء را ذخیره کنید. با این حال بخش هایی از کد را قرار بدید تا بشه کمی جزئیات کار را نگاه کرد.
رسم رو در کدوم Graphics انجام می دهید؟ رسم رو Graphics ای انجام بدهید که منبع اش دائمی باشه، پایدار باشه، قابل ذخیره کردن باشه.
مثلا در Graphics ای رسم کنید که از طریق Graphics.FromImage یا از یک BufferedGraphics بدست اومده چون بعدا می توانید اون Image/Bitmap رو هر جایی که خواستید ذخیره کنید یا BufferedGraphics رو در Bitmap ای رسم کنید و ذخیره کنید.
اما فرضا رسم در e.Graphics ئه pictureBox1_Paint منبعی نداره که دائمی و پایدار باشه.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
public partial class Form1 : Form
{
private BufferedGraphics _buffer;
private Point _p;
private Size _size;
public Form1( )
{
InitializeComponent( );
}
private void Form1_Load( object sender, EventArgs e)
{
using ( var g = pictureBox1. CreateGraphics( ))
{
_buffer = BufferedGraphicsManager. Current.Allocate( g, pictureBox1. ClientRectangle);
_size = pictureBox1. ClientSize;
_buffer.Graphics. Clear( pictureBox1.BackColor);
_buffer.Graphics. SmoothingMode = SmoothingMode. HighQuality;
}
}
private void pictureBox1_MouseMove( object sender, MouseEventArgs e)
{
if (( e.Button != MouseButtons.Left) || ( Math. Pow( e. X - _p. X, 2) + Math. Pow( e. Y - _p. Y, 2) < 100))
{
return;
}
using ( var pen = new Pen( Color. Blue, 8f))
{
_buffer.Graphics. DrawLine( pen, _p, e. Location);
}
_buffer.Graphics. FillEllipse( Brushes. Blue, e. X - 4, e. Y - 4, 8, 8);
_p = e.Location;
pictureBox1.Invalidate();
}
private void pictureBox1_MouseDown( object sender, MouseEventArgs e)
{
if ( e. Button != MouseButtons. Left)
{
return;
}
_p = e.Location;
_buffer.Graphics.FillEllipse( Brushes. Blue, _p. X - 4, _p. Y - 4, 8, 8);
pictureBox1.Invalidate( );
}
private void pictureBox1_Paint( object sender, PaintEventArgs e)
{
if ( _buffer != null)
{
_buffer.Render( e.Graphics);
}
}
private void button1_Click( object sender, EventArgs e)
{
using ( var bitmap = new Bitmap( _size.Width, _size.Height))
{
using ( var g = Graphics.FromImage( bitmap))
{
_buffer.Render( g);
}
bitmap.Save( "test.jpg", ImageFormat.Jpeg);
}
}
}
[
Bitmap bmp_image;
LinearGradientBrush linearBr;
Pen p;
bool click = false;
Point p1, p2;
int x1, x2, y1, y2;
float z;
Graphics g;
string myString;
////
p2 = e.Location;
g.DrawLine(new Pen(colorDialog1.Color, z), p1, p2);
p1 = p2;
سلام دوباره من برا کشیدن خط از کد بالا استفاده کردم یعنی میفرمایین اینا قابل ثبت نیست و کل کدهام رو باید عوض کنم؟؟؟
برا کشیدن دایره،مربع و...؟؟؟
در این کد مشخص نیست، یعنی اون بخشی که g رو مقدار دهی می کنید نمی بینم.
ببینید شما الان یک g دارید که Graphics شما است و باهاش رسم انجام می دهید، تا اینجای کار مشکلی نداره، اما اون g از کجا میاد؟ چه مقداری رو داخل g قرار می دهید؟ اون مهمه.
شما یکجای کد چیزی شبیه به ... = g دارید که اون ... منبع Graphics شما است، فرضا اگر با ()CreateGraphics اون g رو ساخته اید اصولا منبع پایداری نمیشه.
ببینید من در این کد دارم g رو از چی دریافت می کنم؟ از ()Graphics.FromImage
چی رو ذخیره می کنم؟ bmp_image رو.
using System;
using System. Drawing;
using System. Drawing.Imaging;
using System. Windows.Forms;
public partial class Form1 : Form
{
private Bitmap bmp_image;
private Point _p;
private Size _size;
public Form1( )
{
InitializeComponent( );
}
private void Form1_Load( object sender, EventArgs e)
{
bmp_image = new Bitmap( pictureBox1. ClientSize.Width, pictureBox1. ClientSize.Height);
using ( var g = Graphics. FromImage( bmp_image))
{
g.Clear( pictureBox1. BackColor);
}
}
private void pictureBox1_MouseMove( object sender, MouseEventArgs e)
{
if ( ( e.Button != MouseButtons. Left) || ( Math.Pow( e.X - _p.X, 2) + Math.Pow( e.Y - _p.Y, 2) < 100))
{
return;
}
using ( var g = Graphics. FromImage( bmp_image))
{
using ( var pen = new Pen( Color.Blue, 8f))
{
g.DrawLine( pen, _p, e.Location);
}
g.FillEllipse( Brushes. Blue, e.X - 4, e.Y - 4, 8, 8);
}
_p = e.Location;
pictureBox1. Invalidate( );
}
private void pictureBox1_MouseDown( object sender, MouseEventArgs e)
{
if ( e.Button != MouseButtons. Left)
{
return;
}
_p = e.Location;
using ( var g = Graphics. FromImage( bmp_image))
{
g.FillEllipse( Brushes.Blue, _p.X - 4, _p.Y - 4, 8, 8);
}
pictureBox1. Invalidate( );
}
private void pictureBox1_Paint( object sender, PaintEventArgs e)
{
if ( bmp_image != null)
{
var rect = new Rectangle( Point. Empty, bmp_image.Size);
e.Graphics. DrawImage( bmp_image, rect, rect, GraphicsUnit. Pixel);
}
}
private void button1_Click( object sender, EventArgs e)
{
bmp_image.Save( "test.jpg", ImageFormat. Jpeg);
}
}
ببخشید من کد رو نخوندم فقط فکر کردم کارم رو اشتباه انجام دادم الان کد رو کامل می خونم
آخه قبلش فکر کردم فقط روش ذخیره سازی باید فرق داشته بشا واسه اس کیو ال سرور الان کدتون رو می خونم ببینم چی میشه تشکر
با سلام آقا با این روش هم پیاده سازی کردم ولی باز هم نقاشی تو دیتا بیس ذخیره نشد که نشد
public static byte[] ImageToByte(Image photo)
{
ImageConverter conimg = new ImageConverter();
return (byte[])conimg.ConvertTo(photo, typeof(byte[]));
}
command.Parameters.Clear();
command.Connection = connect;
command.CommandText = "insert into naghashi(user_id,save_id,user_img)" +
"values(@user_id,@save_id,@user_img)";
command.Parameters.AddWithValue("@user_id", lblucu.Text);
command.Parameters.AddWithValue("@save_id", lblscode.Text);
Image newImage = picedite.Image;
command.Parameters.AddWithValue("@user_img", ImageToByte(newImage));
connect.Open();
command.ExecuteNonQuery();
connect.Close();
آخرین ویرایش به وسیله HRC123 : دوشنبه 09 فروردین 1400 در 21:39 عصر دلیل: چند خط اضافیی
g = pic1.CreateGraphics();
منظروتون اینه که پیچرباکس رو واسه کارای گرایکی تعریف کردم؟؟؟
جواب داد تشکر فراوان خیلی ممنون
باسلام و عرض شرمندگی
الان باید چه کار کنم که حجم عکسا بیاد پایین که حجم دیتابیس نره خیلی بالا؟
اگه تنوع رنگی و جزئیات کم باشه PNG خوب جواب میده وگرنه فشرده سازی درصدی JPEG رو امتحان کنید، 100 درصد بهترین کیفیت با کمترین فشرده سازی و بیشترین حجم داده رو داره.
هر چقدر درصد پایینتر باشه فشرده سازی افزایش پیدا می کنه اما در عوض کیفیت تصویر هم پایین میاد.
البته JPEG دیگه زمینه شفاف رو مثل PNG پشتیبانی نمی کنه و اگر زمینه تصویر شفاف بود در خروجی مشکی میشه.
using System.Drawing.Imaging;
public static byte[] ImageToByte(Image photo, int qualityPercent)
{
ImageCodecInfo jpgEncoder = null;
foreach (var codec in ImageCodecInfo. GetImageEncoders())
{
if (codec.FormatID == ImageFormat.Jpeg. Guid)
{
jpgEncoder = codec;
break;
}
}
if (jpgEncoder == null)
{
throw new InvalidOperationException();
}
var parameters = new EncoderParameters(1);
parameters.Param [0] = new EncoderParameter( Encoder.Quality, qualityPercent);
using (var stream = new System.IO. MemoryStream())
{
photo.Save(stream, jpgEncoder, parameters);
return stream.ToArray();
}
}
مثلا با کیفیت 50 درصد :
command.Parameters. AddWithValue ("@user_img", ImageToByte (bmp_image, 50));
با کیفیت 85 درصد :
command.Parameters. AddWithValue ("@user_img", ImageToByte (bmp_image, 85));
شما در کدتون دو فرمان SQL داشتید که با update naghashi و insert into naghashi بایت های تصویر رو در پایگاه داده ذخیره میکرد.
بایت های تصویر رو با ImageToByte بدست میاوردید که با ImageConverter.ConvertFrom کار میکرد و خروجی اش بایت های فرمت PNG بود و تنظیم فشرده سازی نداشت.
برای همین یک ImageToByte جدید نوشتم که از فرمت JPEG استفاده کنه و از فشرده سازی JPEG برای کاهش قابل تنظیم حجم داده استفاده کنه.
که بجای اون ImageToByte قبلی از ImageToByte جدید که بجای یک پارامتر ورودی دو پارامتر داره (پارامتر دوم کیفیت تصویر برحسب درصد) استفاده کنید.
در کد ImageToByte جدید ابتدا بین Encoder های موجود که تصویر رو با فرمت های مختلف فشرده می کنند، Encoder مربوط به JPEG رو پیدا می کنیم و در jpgEncoder قرار می دهیم.
سپس یک پارامتر برای تنظیم کیفیت در Encoder ایجاد می کنیم (Encoder.Quality) و تصویر رو با اون Encoder و اون پارامتر کیفیت فشرده و ذخیره می کنیم.
اما ذخیره سازی رو در فایل انجام نمی دهیم، موقتا در حافظه RAM و داخل یک MemoryStream ذخیره اش می کنیم چون قراره دور ریخته بشه.
صرفا پیش از دور ریختنش بایت های ذخیره شده در اون MemoryStream رو بصورت آرایه بایتی از ImageToByte بر میگردونیم.
واسه واکشی تصویر از کامبو باکس هم نظری یا کدی میدید شاید کد های من مشکل داشته باشه
بستگی داره در پایگاه داده و ComboBox چی قرار داده باشید.
یک حالت ساده ای هست که شما میایید برای هر تصویر یک فیلد اسم در نظر می گیرید، مثلا pic_name و در ComboBox فقط اسم اون تصاویر (pic_name ها) رو لیست می کنید.
یعنی ابتدای کار برنامه اسامی تمامی تصاویر موجود در پایگاه داده رو میخونید و در ComboBox لیست می کنید.
و موقعی که یکی شون انتخاب شد بر اساس اون نام کوئری SELECT در پایگاه داده رو اجرا می کنید تا تصویر متناظر اون ComboBox.Text رو در پایگاه داده بخونه و برگردونه و بعد تصویر رو که با SELECT خوندید در bmp_image قرار می دهید و ()picedite.Invalidate رو اجرا می کنید تا تصویر جدید دیده بشه.
یک حالت پیشرفته تری هست که شما فقط اسامی رو ثبت و لیست نمی کنید، یک نمونه کوچک از تصویر شون رو هم ثبت و لیست می کنید (مثلا با نام thumbnail) تا کاربر ببینه عکس اون آیتم ها چه شکلی ئه، شبیه نمایش لایه ها در فتوشاپ یا نمایش آیکون فایل ها در Explorer ویندوز.
پس ابتدای کار برنامه اسم و تصویر بندانگشتی (thumbnail) تمامی رکورد های موجود در پایگاه داده رو میخونید و در ComboBox اسم و یک نمونه تصویر کوچک (نه خود تصویر اصلی چون اون همه تصویر بزرگ حافظه زیادی میخواد) رو نمایش می دهید.
و موقعی که یکی شون انتخاب شد بر اساس اون نام کوئری SELECT در پایگاه داده رو اجرا می کنید تا تصویر متناظر اون ComboBox.Text رو در پایگاه داده بخونه و برگردونه و بعد تصویر اصلی رو که با SELECT خوندید در bmp_image قرار می دهید و ()picedite.Invalidate رو اجرا می کنید تا تصویر جدید دیده بشه.
Image خودش یک متد Image.GetThumbnailImage داره که بتونه از روی تصویر بزرگ نمونه کوچک اش رو در ابعاد فلان بسازه تا موقع ساختن یا ویرایش تصویر اون thumbnail رو هم در پایگاه داده ذخیره کنید.
command.Parameters.Clear();
command.Connection = connect;
command.CommandText = "select user_img from naghashi where pic_name=@pic_name";
command.Parameters.AddWithValue("@pic_name", comboBoxPicName.Text);
connect.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
bmp_image = (Bitmap)ByteToImage(reader["user_img"]);
picedite.Invalidate();
}
}
connect.Close();
حل شد ممنونم