Método de creación de gráficos 8g con doble buffer
Luego, dibuje todos los elementos gráficos en este lienzo y luego use el lienzo para cubrir el fondo del control de visualización para lograr el efecto de "mostrar solo una vez".
Código de implementación (en el método OnPaint):
Rectangle rect = e. ClipRectangle
Bitmap bufferimage = new Bitmap(this. width, this. height);
Gráfica g = gráfica. de imagen (imagen de búfer);
g.clear(este.color de fondo);
g.SmoothingMode = SmoothingMode. Alta calidad; //Alta calidad
g.PixelOffsetMode = PixelOffsetMode. Alta calidad; // alta calidad de desplazamiento de píxeles
foreach(doc . IShape drawobject in draw object list)
{
if (rect.IntersectsWith( drawobject. Rect))
{
Objeto de dibujo. draw(g);
if (drawobject. TrackerState == config. module. core. tracker state. selected
amp amp this. currentoperator == enum. operator. trans from) // Solo se muestran los puntos calientes de las primitivas al editar las operaciones de nodo.
{
Objeto de dibujo. dibujar rastreador(g);
}
}
}
Uso (Gráficos tg = e.Graphics)
{
tg. DrawImage(bufferimage, 0, 0); //Pega el lienzo en la pantalla.
}
b. Cree objetos gráficos directamente en la memoria:
Rectangle rect = e. ClipRectangle
BufferedGraphicsContext contexto actual = BufferedGraphicsManager. actual;
gráficos almacenados en búfer mi búfer = contexto actual. Allocate(e.Graphics, e.clip rectángulo);
Gráficos g = myBuffer. Gráficos;
g.SmoothingMode = SmoothingMode. Alta calidad;
g.PixelOffsetMode = PixelOffsetMode. alta velocidad;
g. clear(this. color de fondo);
foreach(doc. IShape objeto de dibujo en la lista de objetos de dibujo)
{
If (rect.IntersectsWith(drawobject.Rect))
{
DrawObject. dibujar(g);
if (drawobject. TrackerState == config.
módulo .core estado del rastreador seleccionado
amp amp esto. operador actual == enum. operador. trans from)//Solo se muestran los puntos calientes de las primitivas al editar las operaciones de nodo.
{
Objeto de dibujo. draw tracker(g);
}
}
}
Mi búfer. Representación (por ejemplo, gráficos);
g.dispose();
Mi búfer. dispose(); // Libera recursos
En este punto, el problema del doble almacenamiento en búfer está resuelto. Los dos métodos tienen el mismo efecto, pero el último método ocupa muy poca memoria y no provocará pérdidas de memoria.
El siguiente paso es utilizar acdsee para lograr el efecto de arrastrar imágenes. Al principio no entendí el doble búfer y pensé que el doble búfer resolvería este problema. Resultó que el uso de doble buffer no tuvo ningún efecto. Consulté a expertos y luego modifiqué algunos códigos para lograr este efecto.
La imagen está en PictureBox1.
Mapa de bits actual;
bool first = true
cuadro de imagen vacío privado 1 _ MouseDown(remitente del objeto, MouseEventArgs e)
{
if (zoom == 0)
{
if (e.Button == MouseButtons. Left)//arrastrar
mousedrag = e . Ubicación
Imagen miImagen = miMapa. obtener mapa();
currentMap = nuevo mapa de bits (myImage);
primero = false
}
}
cuadro de imagen vacío privado 1 _ MouseMove(remitente del objeto, MouseEventArgs e)
{
if(zoom == 0 amp; amp! first)
{
Imagen img = nuevo mapa de bits(tamaño.ancho,tamaño.alto);
Gráfico g = gráfico. from image(img);
g. Transparent (color. Transparent); //El color de fondo que se muestra después de mover la imagen.
g.SmoothingMode = ModoSuavizado. Alta calidad; //Alta calidad
g.PixelOffsetMode = PixelOffsetMode. Alta calidad; // Alta calidad de desplazamiento de píxeles
g.DrawImageUnscaled(mapa actual, nuevo sistema. Draw.Point(por ejemplo, Ubicación. X - Arrastrar con el mouse. x, e. Ubicación. Y Arrastrar con el mouse. y) ); //Mueve la imagen en G. La imagen original se dibuja en (0, 0), así que usa el nuevo sistema. punto de dibujo (e. ubicación. x-ratón del mouse. x, e.ubicación.y-mousedrag.y).
g.dispose();
imageBox1. Imagen = img//img es una imagen temporal generada cuando el mouse está en esta posición.
}
}
cuadro de imagen vacío privado 1 _ MouseUp(remitente del objeto, MouseEventArgs e)
{
si (zoom == 0)
{
Sistema. dibujo. Haga clic en pnt = nuevo sistema. Dibujo.Punto(ancho / 2 (arrastrar con el mouse. >Mi mapa. centro = mi mapa. ImageToWorld(pnt);
imageBox1. Imagen = miMapa. get map();
first = true
}
}
Hable sobre la idea, cree un mapa de bits y currentMap, use para almacenar la imagen actual. Cuando el mouse se mueve, el dibujo se realiza según la posición del mouse. Finalmente, levanta el mouse y dibuja nuevamente.
El doble buffering es una tecnología básica en gráficos, procesamiento de imágenes y programación. Sabemos que si un formulario requiere un procesamiento de gráficos complejo en respuesta al mensaje WM_PAINT, parpadeará cuando se vuelva a dibujar. Una forma eficaz de resolver este problema es la tecnología de doble buffer. Porque cuando se actualiza el formulario, siempre hay un proceso de borrar la imagen original OnEraseBkgnd, llenar el área de dibujo del formulario con el color de fondo y luego volver a dibujarlo llamando al nuevo código de dibujo, provocando así un contraste en el color de la imagen. Cuando WM_PAINT responde con frecuencia, este contraste se vuelve cada vez más obvio. Entonces vemos parpadeo.
Naturalmente, pensaríamos que evitar el relleno de color de fondo es la forma más directa. Pero en ese caso, la mesa estaría hecha un desastre. Debido a que la imagen original no se limpia cada vez que se dibuja, lo que genera residuos en la imagen, la imagen a menudo se vuelve desordenada cuando se vuelve a dibujar el formulario. Por lo tanto, no basta con desactivar el redibujado en segundo plano. Queríamos volver a dibujar, pero era rápido, así que pensamos en usar la función BitBlt. Puede admitir la copia de alta velocidad de bloques de gráficos. Primero podemos dibujar una imagen en la memoria y luego usar esta función para copiar la imagen completa en primer plano mientras deshabilitamos la actualización de fondo, eliminando así el parpadeo. Lo anterior es la idea básica del dibujo con doble búfer.
Primero proporcione el plan de implementación y luego explique, también usando OnDraw(CDC *pDC):
CDC MemDC//Primero defina un objeto de dispositivo de visualización.
CBitmap MemBitmap//Defina el objeto de mapa de bits
//Luego cree un dispositivo de visualización de memoria compatible con la visualización de la pantalla.
MemDC. CreateCompatibleDC(NULL);
//No puedes dibujar en este momento porque no hay lugar para dibujar_
//Creemos un mapa de bits que sea compatible con la visualización en pantalla. En cuanto al tamaño del mapa de bits, puede usar el tamaño de la ventana o puede definirlo usted mismo (por ejemplo, si hay una barra de desplazamiento, será más grande que el tamaño de la ventana actual, lo que determina qué parte del mapa de bits). la memoria se copia a la pantalla durante BitBlt).
MemBitmap. CreateCompatibleBitmap(pDC, nWidth, n height);
//Seleccione el mapa de bits para el dispositivo de visualización de memoria.
//Solo el dispositivo de visualización de memoria con un mapa de bits seleccionado tiene una ubicación para dibujar en el mapa de bits especificado.
CBitmap *pOldBit=MemDC. Seleccionar objeto (ampMemBitmap);
//Primero borre el mapa de bits con color de fondo. Aquí estoy usando blanco como fondo.
//También puedes utilizar tus propios colores.
MemDC.
FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));
//Dibujo
MemDC. mover a(...);
MemDC. line to(……);
//Copiar el mapa en la memoria a la pantalla.
pDC->; BitBlt(0, 0, nWidth, nHeight, ampMemDC, 0, 0, src copy);
//Limpiar después de completar el dibujo
//Seleccione el pOldBit anterior para regresar. Elimine MemBitmap del dispositivo antes de eliminarlo.
MemDC. seleccionar objeto(pold bit);
MemBitmap. eliminar objeto();
MemDC. DeleteDC();
Cierre suave bidireccional