private void bpCapture_Click(object sender, EventArgs e) { int numSpr = (int)numSprite.Value; for (int spry = 0; spry < captSize; spry++) { for (int sprx = 0; sprx < captSize; sprx++) { for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { int pen = 0; RvbColor col = bmp.GetPixelColor((x << 3) + (sprx << 7), (y << 3) + (spry << 7)); for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (BitmapCpc.Palette[pen] >> 8) && (col.b >> 4) == ((BitmapCpc.Palette[pen] >> 4) & 0x0F) && (col.r >> 4) == (BitmapCpc.Palette[pen] & 0x0F)) { break; } } BitmapCpc.spritesHard[comboBanque.SelectedIndex, numSpr, x, y] = (byte)(pen & 0x0F); } } numSpr++; } } // Copie de la palette image dans la palette des sprites for (int c = 0; c < 16; c++) { BitmapCpc.paletteSprite[c] = BitmapCpc.Palette[c]; } MessageBox.Show("Capture Ok."); }
private void DrawMatrice() { for (int spr = 0; spr < 16; spr++) { for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { int col = BitmapCpc.paletteSprite[BitmapCpc.spritesHard[numBank, spr, x, y]]; RvbColor c = new RvbColor((byte)((col & 0x0F) * 17), (byte)(((col & 0xF00) >> 8) * 17), (byte)(((col & 0xF0) >> 4) * 17)); for (int zx = 0; zx < (x == 15 ? 3 : 4); zx++) { for (int zy = 0; zy < 4; zy++) { bmpAllSprites.SetPixel(zx + ((x + (spr << 4)) << 2), zy + (y << 2), c); } } if (spr == numSprite) { for (int zx = 0; zx < 38; zx++) { for (int zy = 0; zy < 38; zy++) { bmpSprite.SetPixel(zx + (x * 40), zy + (y * 40), c); } } } } } } pictAllSprites.Refresh(); pictEditSprite.Refresh(); }
private int GetPenColor(DirectBitmap bmpLock, int x, int y) { int pen = 0; RvbColor col = bmpLock.GetPixelColor(x, y); if (cpcPlus) { for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (Palette[pen] >> 8) && (col.r >> 4) == ((Palette[pen] >> 4) & 0x0F) && (col.b >> 4) == (Palette[pen] & 0x0F)) { break; } } } else { for (pen = 0; pen < 16; pen++) { RvbColor fixedCol = RgbCPC[Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } return(pen); }
private int GetAsciiMat(DirectBitmap bmpLock, int x, int y) { for (int i = 0; i < 16; i++) { bool found = true; for (int ym = 0; ym < 4; ym++) { for (int xm = 0; xm < 4; xm++) { RvbColor pix = bmpLock.GetPixelColor(x + (xm << 1), y + (ym << 1)); RvbColor c = GetColorPal(trameM1[i, xm, ym]); if (c.r != pix.r || c.v != pix.v || c.b != pix.b) { found = false; break; } } } if (found) { return(i); } } return(0); }
static public void DoDitherFull(DirectBitmap source, int xPix, int yPix, int Tx, RvbColor p, RvbColor choix, bool diffErr) { if (diffErr) { for (int y = 0; y < matDither.GetLength(1); y++) { for (int x = 0; x < matDither.GetLength(0); x++) { if (xPix + Tx * x < source.Width && yPix + 2 * y < source.Height) { RvbColor pix = source.GetPixelColor(xPix + Tx * x, yPix + (y << 1)); pix.r = MinMaxByte((double)pix.r + (p.r - choix.r) * matDither[x, y] / 256.0); pix.v = MinMaxByte((double)pix.v + (p.v - choix.v) * matDither[x, y] / 256.0); pix.b = MinMaxByte((double)pix.b + (p.b - choix.b) * matDither[x, y] / 256.0); source.SetPixel(xPix + Tx * x, yPix + (y << 1), pix); } } } } else { int xm = (xPix / Tx) % matDither.GetLength(0); int ym = ((yPix) >> 1) % matDither.GetLength(1); p.r = MinMaxByte((double)p.r + matDither[xm, ym]); p.v = MinMaxByte((double)p.v + matDither[xm, ym]); p.b = MinMaxByte((double)p.b + matDither[xm, ym]); } }
static private int GetNumColorPixelCpc(Param prm, RvbColor p) { int indexChoix = 0; if (!prm.newMethode) { indexChoix = (p.r > prm.cstR2 ? 6 : p.r > prm.cstR1 ? 3 : 0) + (p.b > prm.cstB2 ? 2 : p.b > prm.cstB1 ? 1 : 0) + (p.v > prm.cstV2 ? 18 : p.v > prm.cstV1 ? 9 : 0); } else { int oldDist = 0x7FFFFFFF; for (int i = 0; i < 27; i++) { RvbColor s = BitmapCpc.RgbCPC[i]; int dist = (s.r - p.r) * (s.r - p.r) * prm.coefR + (s.v - p.v) * (s.v - p.v) * prm.coefV + (s.b - p.b) * (s.b - p.b) * prm.coefB; if (dist < oldDist) { oldDist = dist; indexChoix = i; if (dist == 0) { break; } } } } return(indexChoix); }
// Changement de la palette private void ClickColor(object sender, MouseEventArgs e) { Label colorClick = sender as Label; int pen = colorClick.Tag != null ? (int)colorClick.Tag : 0; if (e.Button == MouseButtons.Right) { int col = BitmapCpc.paletteSprite[pen]; RvbColor colRvb = new RvbColor((byte)((col & 0x0F) * 17), (byte)(((col & 0xF00) >> 8) * 17), (byte)(((col & 0xF0) >> 4) * 17)); EditColor ed = new EditColor(main, pen, col, colRvb.GetColor, true); ed.ShowDialog(this); if (ed.isValide) { BitmapCpc.paletteSprite[pen] = ed.ValColor; col = ed.ValColor; colors[pen].BackColor = Color.FromArgb((byte)((col & 0x0F) * 17), (byte)(((col & 0xF00) >> 8) * 17), (byte)(((col & 0xF0) >> 4) * 17)); colors[pen].Refresh(); DrawMatrice(); } } else { penLeft = (byte)pen; DrawPens(); } }
public void SetPixel(int x, int y, RvbColor color) { if (y < Height) { tabBits[x + (y * Width)] = (uint)color.GetColorArgb | 0xFF000000; } }
// // Passe 1 : Réduit la palette aux x couleurs de la palette du CPC. // Effectue également un traitement de l'erreur (tramage) si demandé. // Calcule le nombre de couleurs utilisées dans l'image, et // remplit le tableau coulTrouvee avec ces couleurs // static private void ConvertPasse1(DirectBitmap source, ImageCpc dest, Param prm) { int pct = Dither.SetMatDither(prm); RvbColor p = new RvbColor(0), choix, n1, n2; int indexChoix = 0; int incY = prm.trameTc ? 4 : 2; for (int yPix = 0; yPix < BitmapCpc.TailleY; yPix += incY) { int Tx = BitmapCpc.CalcTx(yPix); for (int xPix = 0; xPix < BitmapCpc.TailleX; xPix += Tx) { for (int yy = 0; yy < incY; yy += 2) { p = GetPixel(source, xPix, yy + yPix, Tx, prm, pct); // Recherche le point dans la couleur cpc la plus proche if (prm.cpcPlus) { choix = new RvbColor((byte)((p.r >> 4) * 17), (byte)((p.v >> 4) * 17), (byte)((p.b >> 4) * 17)); indexChoix = ((choix.v << 4) & 0xF00) + ((choix.b) & 0xF0) + ((choix.r) >> 4); } else { indexChoix = GetNumColorPixelCpc(prm, p); choix = BitmapCpc.RgbCPC[indexChoix]; } coulTrouvee[indexChoix, yPix >> 1]++; if (!prm.trameTc) { source.SetPixel(xPix, yy + yPix, prm.setPalCpc ? choix : p); } } if (prm.trameTc) { // Moyenne des 2 pixels RvbColor p0 = GetPixel(source, xPix, yPix, Tx, prm, pct); RvbColor p1 = GetPixel(source, xPix, yPix + 2, Tx, prm, pct); int r = (p0.r + p1.r); int v = (p0.v + p1.v); int b = (p0.b + p1.b); if (prm.cpcPlus) { n1 = new RvbColor((byte)((r >> 4) * 8), (byte)((v >> 4) * 8), (byte)((b >> 4) * 8)); n2 = new RvbColor((byte)((r >> 5) * 8), (byte)((v >> 5) * 8), (byte)((b >> 5) * 8)); } else { n1 = BitmapCpc.RgbCPC[(r > prm.cstR3 ? 6 : r > prm.cstR1 ? 3 : 0) + (v > prm.cstV3 ? 18 : v > prm.cstV1 ? 9 : 0) + (b > prm.cstB3 ? 2 : b > prm.cstB1 ? 1 : 0)]; n2 = BitmapCpc.RgbCPC[(r > prm.cstR4 ? 6 : r > prm.cstR2 ? 3 : 0) + (v > prm.cstV4 ? 18 : v > prm.cstV2 ? 9 : 0) + (b > prm.cstB4 ? 2 : b > prm.cstB2 ? 1 : 0)]; } source.SetPixel(xPix, yPix, (xPix & Tx) == 0 ? n1 : n2); source.SetPixel(xPix, yPix + 2, (xPix & Tx) == 0 ? n2 : n1); } } } }
public void SauvePng(string fileName, Param param) { if (BitmapCpc.modeVirtuel == 6) { string singleName = Path.GetDirectoryName(fileName) + "\\" + Path.GetFileNameWithoutExtension(fileName); DirectBitmap bmpRaster = new DirectBitmap(BmpLock.Bitmap.Width >> 1, BmpLock.Bitmap.Height >> 1); //DirectBitmap bmp4Cols = new DirectBitmap(BmpLock.Bitmap.Width >> 1, BmpLock.Bitmap.Height >> 1); RvbColor c2 = new RvbColor(0); int posx = 0; for (int y = 0; y < bmpRaster.Height; y++) { bool memoC = false; for (int x = 0; x < bmpRaster.Width; x++) { RvbColor c = BmpLock.GetPixelColor(x << 1, y << 1); for (int i = 0; i < 16; i++) { RvbColor p = BitmapCpc.RgbCPC[colMode5[y, i]]; if (p.r == c.r && p.v == c.v && p.b == c.b) { if (i > 2) { //c = BitmapCpc.RgbCPC[colMode5[y, 3]]; c2 = p; int start = memoC ? x & 0xFF8 : 0; memoC = true; for (int r = start; r < x; r++) { bmpRaster.SetPixel(r, y, c2); } // posx = 0; } break; } } //bmp4Cols.SetPixel(x, y, c); bmpRaster.SetPixel(x, y, c2); posx++; } } bmpRaster.Bitmap.Save(singleName + "_Rasters" + ".png", System.Drawing.Imaging.ImageFormat.Png); bitmapCpc.CreeBmpCpcForceMode1(BmpLock); SauveImage.SauveScr(singleName + ".scr", bitmapCpc, this, param, false); } else { BmpLock.Bitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png); } main.SetInfo("Sauvegarde image PNG ok."); }
// Calcul automatique matrice 4x4 en mode 1 static public void CnvTrame(DirectBitmap source, Param prm, ImageCpc dest, List <TrameM1> lstTrame, Param p) { p.modeVirtuel = 1; ConvertPasse1(source, dest, p); RechercheCMax(4, p.lockState, p); for (int y = 0; y < BitmapCpc.TailleY; y += 8) { for (int x = 0; x < BitmapCpc.TailleX; x += 8) { TrameM1 locTrame = new TrameM1(); for (int maty = 0; maty < 4; maty++) { for (int matx = 0; matx < 4; matx++) { RvbColor pix = source.GetPixelColor(x + (matx << 1), y + (maty << 1)); int oldDist = 0x7FFFFFFF; int choix = 0; for (int i = 0; i < 4; i++) { RvbColor c = dest.bitmapCpc.GetColorPal(i); int dist = (c.r - pix.r) * (c.r - pix.r) * prm.coefR + (c.v - pix.v) * (c.v - pix.v) * prm.coefV + (c.b - pix.b) * (c.b - pix.b) * prm.coefB; if (dist < oldDist) { choix = i; oldDist = dist; if (dist == 0) { i = 4; } } } locTrame.SetPix(matx, maty, choix); } } bool found = false; foreach (TrameM1 t in lstTrame) { if (t.IsSame(locTrame, 4)) { found = true; break; } } if (!found) { lstTrame.Add(locTrame); } } } }
// Conversion "standard" static private void SetPixCol(DirectBitmap bitmap, Param prm, ImageCpc dest, int maxPen, RvbColor[,] tabCol) { int incY = BitmapCpc.modeVirtuel >= 8 && BitmapCpc.modeVirtuel <= 10 ? 8 : 2; RvbColor pix; for (int y = 0; y < BitmapCpc.TailleY; y += incY) { int Tx = BitmapCpc.CalcTx(y); maxPen = BitmapCpc.MaxPen(y); for (int x = 0; x < BitmapCpc.TailleX; x += Tx) { int oldDist = 0x7FFFFFFF; int r = 0, v = 0, b = 0; for (int j = 0; j < incY; j += 2) { pix = bitmap.GetPixelColor(x, y + j); r += pix.r; v += pix.v; b += pix.b; } r = r / (incY >> 1); v = v / (incY >> 1); b = b / (incY >> 1); pix = new RvbColor((byte)r, (byte)v, (byte)b); int choix = 0; for (int i = 0; i < maxPen; i++) { RvbColor c = tabCol[i, y >> 1]; if (c != null) { int dist = (c.r - pix.r) * (c.r - pix.r) * prm.coefR + (c.v - pix.v) * (c.v - pix.v) * prm.coefV + (c.b - pix.b) * (c.b - pix.b) * prm.coefB; if (dist < oldDist) { choix = i; oldDist = dist; if (dist == 0) { i = maxPen; } } } } for (int j = 0; j < incY; j += 2) { dest.SetPixelCpc(x, y + j, choix, Tx); } } } }
private byte[] MakeSprite() { byte[] ret = new byte[(BitmapCpc.TailleX * BitmapCpc.TailleY) >> 4]; Array.Clear(ret, 0, ret.Length); for (int y = 0; y < BitmapCpc.TailleY; y += 2) { int tx = BitmapCpc.CalcTx(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { byte pen = 0, octet = 0; for (int p = 0; p < 8; p++) { if ((p % tx) == 0) { RvbColor col = BmpLock.GetPixelColor(x + p, y); if (BitmapCpc.cpcPlus) { for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (BitmapCpc.Palette[pen] >> 8) && (col.r >> 4) == ((BitmapCpc.Palette[pen] >> 4) & 0x0F) && (col.b >> 4) == (BitmapCpc.Palette[pen] & 0x0F)) { break; } } } else { for (pen = 0; pen < 16; pen++) { RvbColor fixedCol = BitmapCpc.RgbCPC[BitmapCpc.Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } if (pen > 15) { pen = 0; // Pb peut survenir si la palette n'est pas la même pour chaque image d'une animation... } octet |= (byte)(tabOctetMode[pen % 16] >> (p / tx)); } } ret[(x >> 3) + (y >> 1) * (BitmapCpc.TailleX >> 3)] = octet; } } return(ret); }
// Conversion avec trames précalculées en mode 1 static private void SetPixTrameM1(DirectBitmap bitmap, Param prm, ImageCpc dest, int maxPen, RvbColor[,] tabCol) { for (int y = 0; y <= BitmapCpc.TailleY - 8; y += 8) { maxPen = BitmapCpc.MaxPen(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { int choix = 0, oldDist = 0x7FFFFFFF; for (int i = 0; i < 16; i++) { int dist = 0, r1 = 0, v1 = 0, b1 = 0, r2 = 0, v2 = 0, b2 = 0; for (int ym = 0; ym < 4; ym++) { for (int xm = 0; xm < 4; xm++) { RvbColor pix = bitmap.GetPixelColor(x + (xm << 1), y + (ym << 1)); RvbColor c = tabCol[BitmapCpc.trameM1[i, xm, ym], ym + (y >> 1)]; r1 += pix.r; v1 += pix.v; b1 += pix.b; r2 += c.r; v2 += c.v; b2 += c.b; } } dist = Math.Abs(r1 - r2) * prm.coefR + Math.Abs(v1 - v2) * prm.coefV + Math.Abs(b1 - b2) * prm.coefB; if (dist < oldDist) { choix = i; oldDist = dist; if (dist == 0) { i = 16; } } } for (int ym = 0; ym < 4; ym++) { for (int xm = 0; xm < 4; xm++) { dest.SetPixelCpc(x + (xm << 1), y + (ym << 1), BitmapCpc.trameM1[choix, xm, ym], 2); } } } } }
// Conversion avec des "splits-rasters" static private void SetPixColSplit(DirectBitmap bitmap, Param prm, ImageCpc dest, RvbColor[,] tabCol) { for (int y = 0; y < BitmapCpc.TailleY; y += 2) { int tailleSplit = 0, colSplit = -1; for (int x = 0; x < BitmapCpc.TailleX; x += 2) { int oldDist = 0x7FFFFFFF; RvbColor pix = bitmap.GetPixelColor(x, y); int choix = 0, memoPen = 0; for (int i = 0; i < 9; i++) { memoPen = i; if (colSplit != -1 && tailleSplit < 32 && i > 2) { memoPen = colSplit; } RvbColor c = tabCol[memoPen, y >> 1]; int dist = (c.r - pix.r) * (c.r - pix.r) * prm.coefR + (c.v - pix.v) * (c.v - pix.v) * prm.coefV + (c.b - pix.b) * (c.b - pix.b) * prm.coefB; if (dist < oldDist) { choix = memoPen; oldDist = dist; if (dist == 0 || memoPen == colSplit) { i = 9; } } } if (choix > 2) { if (colSplit != choix) { colSplit = choix; tailleSplit = 0; } } //if (choix == colSplit) tailleSplit++; dest.SetPixelCpc(x, y, choix, 2); } } }
private void DrawTrame() { bpPrev.Visible = numTrame > 0; bpSuiv.Visible = numTrame < 15; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { for (int zx = 0; zx < 78; zx++) { for (int zy = 0; zy < 78; zy++) { RvbColor c = bmpCpc.GetColorPal(BitmapCpc.trameM1[numTrame, x, y]); bmpTrame.SetPixel(zx + (x * 80), zy + (y * 80), c); } } } } pictEditMatrice.Refresh(); }
public void CreeBmpCpc(DirectBitmap bmpLock, int[,] colMode5, bool egx = false, int lignestart = 0) { System.Array.Clear(bmpCpc, 0, bmpCpc.Length); for (int y = 0; y < TailleY; y += 2) { int adrCPC = GetAdrCpc(y); int tx = CalcTx(y); int maxPen = MaxPen(y); for (int x = 0; x < TailleX; x += 8) { byte pen = 0, octet = 0, decal = 0; if (!egx || ((y >> 1) & 1) == lignestart) { for (int p = 0; p < 8; p += tx) { RvbColor col = bmpLock.GetPixelColor(x + p, y); for (pen = 0; pen < maxPen; pen++) { if (cpcPlus) { if ((col.v >> 4) == (Palette[pen] >> 8) && (col.b >> 4) == ((Palette[pen] >> 4) & 0x0F) && (col.r >> 4) == (Palette[pen] & 0x0F)) { break; } } else { RvbColor fixedCol = RgbCPC[modeVirtuel == 5 || modeVirtuel == 6 ? colMode5[y >> 1, pen] : Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } octet |= (byte)(tabOctetMode[pen % 16] >> (decal++)); } bmpCpc[adrCPC + (x >> 3)] = octet; } } } }
private void DrawSpriteTest(DirectBitmap bmp, int spr, int ofsx, int ofsy) { int taillex = 1 << (int)zoomX.Value; int tailley = 2 << (int)zoomY.Value; for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { for (int zx = 0; zx < taillex; zx++) { for (int zy = 0; zy < tailley; zy++) { int col = BitmapCpc.paletteSprite[BitmapCpc.spritesHard[numBank, spr, x, y]]; RvbColor c = new RvbColor((byte)((col & 0x0F) * 17), (byte)(((col & 0xF00) >> 8) * 17), (byte)(((col & 0xF0) >> 4) * 17)); bmp.SetPixel(zx + (x * taillex) + ofsx, zy + (y * tailley) + ofsy, c); } } } } }
private void DrawSprite() { lblSelSprite.Text = "Sprite n° : " + numSprite.ToString(); bpPrev.Visible = numSprite > 0; bpSuiv.Visible = numSprite < 15; for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { int col = BitmapCpc.paletteSprite[BitmapCpc.spritesHard[numBank, numSprite, x, y]]; RvbColor c = new RvbColor((byte)((col & 0x0F) * 17), (byte)(((col & 0xF00) >> 8) * 17), (byte)(((col & 0xF0) >> 4) * 17)); for (int zx = 0; zx < 38; zx++) { for (int zy = 0; zy < 38; zy++) { bmpSprite.SetPixel(zx + (x * 40), zy + (y * 40), c); } } } } pictEditSprite.Refresh(); }
public void CreeBmpCpcForceMode1(DirectBitmap bmpLock) { System.Array.Clear(bmpCpc, 0, bmpCpc.Length); for (int y = 0; y < TailleY; y += 2) { int adrCPC = GetAdrCpc(y); int tx = CalcTx(y); int maxPen = MaxPen(y); for (int x = 0; x < TailleX; x += 8) { byte pen = 0, octet = 0, decal = 0; for (int p = 0; p < 8; p += tx) { RvbColor col = bmpLock.GetPixelColor(x + p, y); for (pen = 0; pen < maxPen; pen++) { if (cpcPlus) { if ((col.v >> 4) == (Palette[pen] >> 8) && (col.b >> 4) == ((Palette[pen] >> 4) & 0x0F) && (col.r >> 4) == (Palette[pen] & 0x0F)) { break; } } else { RvbColor fixedCol = RgbCPC[Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } octet |= (byte)(tabOctetMode[Math.Min(3, (int)pen)] >> (decal++)); } bmpCpc[adrCPC + (x >> 3)] = octet; } } }
// Changement de la palette private void ClickColor(object sender, MouseEventArgs e) { Label colorClick = sender as Label; int pen = colorClick.Tag != null ? (int)colorClick.Tag : 0; if (!modeEdition.Checked) { EditColor ed = new EditColor(main, pen, BitmapCpc.Palette[pen], bitmapCpc.GetColorPal(pen).GetColorArgb, BitmapCpc.cpcPlus); ed.ShowDialog(this); if (ed.isValide) { BitmapCpc.Palette[pen] = ed.ValColor; lockColors[pen].Checked = true; lockState[pen] = 1; UpdatePalette(); Convert(false); } } else { if (editToolMode != EditTool.Draw) { rbDraw.Checked = true; } RvbColor col = bitmapCpc.GetColorPal(pen); if (e.Button == System.Windows.Forms.MouseButtons.Left) { drawCol = pen; drawColor.BackColor = Color.FromArgb(col.r, col.v, col.b); } else { undrawCol = pen; undrawColor.BackColor = Color.FromArgb(col.r, col.v, col.b); } } }
private void SetPixelSprite(int x, int y) { int col = BitmapCpc.paletteSprite[BitmapCpc.spritesHard[numBank, numSprite, x, y]]; RvbColor c = new RvbColor((byte)((col & 0x0F) * 17), (byte)(((col & 0xF00) >> 8) * 17), (byte)(((col & 0xF0) >> 4) * 17)); for (int zx = 0; zx < 38; zx++) { for (int zy = 0; zy < 38; zy++) { bmpSprite.SetPixel(zx + (x * 40), zy + (y * 40), c); } } for (int zx = 0; zx < (x == 15 ? 3 : 4); zx++) { for (int zy = 0; zy < 4; zy++) { bmpAllSprites.SetPixel(zx + ((x + (numSprite << 4)) << 2), zy + (y << 2), c); } } pictEditSprite.Refresh(); pictAllSprites.Refresh(); }
private void DrawMatrice() { DirectBitmap bmp = new DirectBitmap(pictAllMatrice.Width, pictAllMatrice.Height); pictAllMatrice.Image = bmp.Bitmap; for (int i = 0; i < 16; i++) { for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { for (int zx = 0; zx < (x == 3 ? 7 : 8); zx++) { for (int zy = 0; zy < 8; zy++) { RvbColor c = bmpCpc.GetColorPal(BitmapCpc.trameM1[i, x, y]); bmp.SetPixel(zx + ((x + (i << 2)) << 3), zy + (y << 3), c); } } } } } pictAllMatrice.Refresh(); }
// // Passe 2 : réduit l'image à MaxPen couleurs. // static private void Passe2(DirectBitmap source, ImageCpc dest, Param p, ref int colSplit) { RvbColor[,] tabCol = new RvbColor[16, 272]; int[] MemoLockState = new int[16]; int i; int Tx = BitmapCpc.CalcTx(); int maxPen = BitmapCpc.MaxPen(2); for (i = 0; i < 16; i++) { MemoLockState[i] = p.lockState[i]; } if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4) { int newMax = BitmapCpc.MaxPen(0); RechercheCMax(newMax, MemoLockState, p); for (i = 0; i < newMax; i++) { MemoLockState[i] = 1; } } if (BitmapCpc.modeVirtuel == 5 || BitmapCpc.modeVirtuel == 6) { if (BitmapCpc.modeVirtuel == 5) { colSplit = RechercheCMaxModeX(dest.colMode5, MemoLockState, BitmapCpc.TailleY, p); } else { colSplit = RechercheCMaxModeSplit(dest.colMode5, MemoLockState, BitmapCpc.TailleY, p); maxPen = 9; } // réduit l'image à MaxPen couleurs. for (int y = 0; y < BitmapCpc.TailleY >> 1; y++) { for (i = 0; i < maxPen; i++) { tabCol[i, y] = p.cpcPlus ? new RvbColor((byte)((dest.colMode5[y, i] & 0x0F) * 17), (byte)(((dest.colMode5[y, i] & 0xF00) >> 8) * 17), (byte)(((dest.colMode5[y, i] & 0xF0) >> 4) * 17)) : BitmapCpc.RgbCPC[dest.colMode5[y, i] < 27 ? dest.colMode5[y, i] : 0]; } } } else { RechercheCMax(maxPen, MemoLockState, p); // réduit l'image à MaxPen couleurs. for (int y = 0; y < BitmapCpc.TailleY; y += 2) { maxPen = BitmapCpc.MaxPen(y); for (i = 0; i < maxPen; i++) { tabCol[i, y >> 1] = dest.bitmapCpc.GetColorPal(i); } } } switch (BitmapCpc.modeVirtuel) { case 6: SetPixColSplit(source, p, dest, tabCol); break; case 7: SetPixTrameM1(source, p, dest, maxPen, tabCol); break; default: SetPixCol(source, p, dest, maxPen, tabCol); break; } }
// // Passe 1 : Réduit la palette aux x couleurs de la palette du CPC. // Effectue également un traitement de l'erreur (tramage) si demandé. // Calcule le nombre de couleurs utilisées dans l'image, et // remplit un tableau avec ces couleurs // static private int ConvertPasse1(int xdest, int ydest, int Methode, int Matrice, int Pct, bool cpcPlus, bool newMethode, int Mode, bool CpcPlus, bool ReductPal1, bool ReductPal2, bool ModeReduct, int pctLumi, int pctSat, int pctContrast) { if (cpcPlus) { Pct <<= 2; } for (int i = 0; i < Coul.Length; i++) { Coul[i] = 0; } float lumi = pctLumi / 100.0F; float satur = pctSat / 100.0F; double c = pctContrast / 100.0; for (int i = 0; i < 256; i++) { double contrast = ((((i / 255.0) - 0.5) * c) + 0.5) * 255; tblContrast[i] = (byte)MinMax((int)contrast, 0, 255); } fctCalcDiff = null; if (Pct > 0) { switch (Matrice) { case 2: switch (Methode) { case 1: fctCalcDiff = CalcDiffMethode1Mat2; coeffMat = 1600 / Pct; break; case 2: fctCalcDiff = CalcDiffMethode2Mat2; coeffMat = 1500 / Pct; break; case 3: fctCalcDiff = CalcDiffMethode3Mat2; coeffMat = 800 / Pct; break; } break; case 3: switch (Methode) { case 1: fctCalcDiff = CalcDiffMethode1Mat3; coeffMat = 4800 / Pct; break; case 2: fctCalcDiff = CalcDiffMethode2Mat3; coeffMat = 1600 / Pct; break; case 3: fctCalcDiff = CalcDiffMethode3Mat3; coeffMat = 1600 / Pct; break; } break; } } RvbColor choix, p = new RvbColor(0); /* * long totalr = 0, totalv = 0, totalb = 0; * for (xPix = 0; xPix < xdest; xPix += Tx) * for (yPix = 0; yPix < ydest; yPix += 2) { * // Lecture de la couleur du point au coordonnées (x,y) * RvbColor p = bitmap.GetPixelColor(xPix, yPix); * totalr += p.red - 127; * totalv += p.green - 127; * totalb += p.blue - 127; * } */ for (xPix = 0; xPix < xdest; xPix += Tx) { for (yPix = 0; yPix < ydest; yPix += 2) { // Lecture de la couleur du point au coordonnées (x,y) /*int totr = 0, totv = 0, totb = 0, cnt = 0; ; * for (int i = 0; i < Tx; i++) * for (int j = 0; j < 2; j++) { * p = bitmap.GetPixelColor(xPix + j, yPix + j); * totr += p.red; * totb += p.blue; * totv += p.green; * cnt++; * } * p.red = totr / cnt; * p.green = totv / cnt; * p.blue = totb / cnt;*/ p = bitmap.GetPixelColor(xPix, yPix); if (p.red != 0 && p.green != 0 && p.blue != 0) { float r = tblContrast[p.red]; float v = tblContrast[p.green]; float b = tblContrast[p.blue]; if (pctLumi != 100 || pctSat != 100) { SetLumiSat(lumi, satur, ref r, ref v, ref b); } p.red = (byte)MinMax((int)r, 0, 255); p.green = (byte)MinMax((int)v, 0, 255); p.blue = (byte)MinMax((int)b, 0, 255); } // Recherche le point dans la couleur cpc la plus proche int indexChoix = 0; if (cpcPlus) { choix = new RvbColor((byte)((p.red >> 4) * 17), (byte)((p.green >> 4) * 17), (byte)((p.blue >> 4) * 17)); indexChoix = ((choix.green << 4) & 0xF00) + ((choix.red) & 0xF0) + ((choix.blue) >> 4); } else { if (!newMethode) { indexChoix = (p.red > SEUIL_LUM_2 ? 2 : p.red > SEUIL_LUM_1 ? 1 : 0) + (p.blue > SEUIL_LUM_2 ? 6 : p.blue > SEUIL_LUM_1 ? 3 : 0) + (p.green > SEUIL_LUM_2 ? 18 : p.green > SEUIL_LUM_1 ? 9 : 0); } else { int OldDist1 = 0x7FFFFFFF; for (int i = 0; i < 27; i++) { RvbColor s = BitmapCpc.RgbCPC[i]; int Dist1 = CalcDist(s.red, s.green, s.blue, p.red, p.green, p.blue); if (Dist1 < OldDist1) { OldDist1 = Dist1; indexChoix = i; if (Dist1 == 0) { break; } } } } choix = BitmapCpc.RgbCPC[indexChoix]; } Coul[indexChoix]++; if (fctCalcDiff != null) { // Modifie composante Rouge fctCalcDiff(p.red - choix.red, 0); // Modifie composante Verte fctCalcDiff(p.green - choix.green, 1); // Modifie composante Bleue fctCalcDiff(p.blue - choix.blue, 2); } bitmap.SetPixel(xPix, yPix, choix.GetColor); } } if (CpcPlus) { // // Réduction du nombre de couleurs pour éviter les couleurs // trop proches // if (Mode < 3) { // Masquer 1 bit par composante for (int i = 0; i < Coul.Length; i++) { if (((i & 1) == 1 && ReductPal1) || ((i & 1) == 0 && ReductPal2)) { int c1 = (i & 0xC00) * 0xFFF / 0xC00; int c2 = (i & 0xC0) * 0xFF / 0xC0; int c3 = (i & 0x0C) * 0x0F / 0x0C; int t = Coul[i]; Coul[i] = 0; if (ModeReduct) { Coul[(c1 & 0xF00) + (c2 & 0xF0) + (c3 & 0x0F)] += t; } else { Coul[(c1 & 0xC00) + (c2 & 0xC0) + (c3 & 0x0C)] += t; } } } } } int NbCol = 0; for (int i = 0; i < Coul.Length; i++) { if (Coul[i] > 0) { NbCol++; } } return(NbCol); }
// // Recherche les x meilleurs couleurs parmis les n possibles (remplit le tableau BitmapCpc.Palette) // static void RechercheCMax(int maxPen, int[] lockState, Param p) { int cUtil, x, FindMax = BitmapCpc.cpcPlus ? 4096 : 27, valMax = 0; for (x = 0; x < maxPen; x++) { if (lockState[x] > 0) { for (int y = 0; y < 272; y++) { coulTrouvee[BitmapCpc.Palette[x], y] = 0; } } } // Recherche la couleur la plus utilisée for (cUtil = 0; cUtil < maxPen; cUtil++) { valMax = 0; if (lockState[cUtil] == 0) { for (int i = 0; i < FindMax; i++) { int nbc = 0; for (int y = 0; y < 272; y++) { nbc += coulTrouvee[i, y]; } if (valMax < nbc) { valMax = nbc; BitmapCpc.Palette[cUtil] = i; } } for (int y = 0; y < 272; y++) { coulTrouvee[BitmapCpc.Palette[cUtil], y] = 0; } if (p.newReduc) { break; // Première couleur trouvée => sortie } } } if (p.newReduc) // Méthode altenative recherche de couleurs : les plus différentes parmis les plus utilisées { RvbColor colFirst = BitmapCpc.cpcPlus ? new RvbColor((byte)((BitmapCpc.Palette[cUtil] & 0x0F) * 17), (byte)(((BitmapCpc.Palette[cUtil] & 0xF00) >> 8) * 17), (byte)(((BitmapCpc.Palette[cUtil] & 0xF0) >> 4) * 17)) : BitmapCpc.RgbCPC[BitmapCpc.Palette[cUtil]]; bool takeDist = false; for (x = 0; x < maxPen; x++) { if (takeDist) { valMax = 0; if (lockState[x] == 0) { for (int i = 0; i < FindMax; i++) { int nbc = 0; for (int y = 0; y < 272; y++) { nbc += coulTrouvee[i, y]; } if (valMax < nbc) { valMax = nbc; BitmapCpc.Palette[x] = i; } } } } else { if (lockState[x] == 0 && x != cUtil) { int dist, oldDist = 0; for (int rech = 4; rech-- > 0;) { for (int i = 0; i < FindMax; i++) { int nbc = 0; for (int y = 0; y < 272; y++) { nbc += coulTrouvee[i, y]; } if (nbc > valMax >> rech) { RvbColor c = BitmapCpc.cpcPlus ? new RvbColor((byte)((i & 0x0F) * 17), (byte)(((i & 0xF00) >> 8) * 17), (byte)(((i & 0xF0) >> 4) * 17)) : BitmapCpc.RgbCPC[i]; dist = (c.r - colFirst.r) * (c.r - colFirst.r) * p.coefR + (c.v - colFirst.v) * (c.v - colFirst.v) * p.coefV + (c.b - colFirst.b) * (c.b - colFirst.b) * p.coefB; if (dist > oldDist) { oldDist = dist; BitmapCpc.Palette[x] = i; } } } } if (oldDist == 0) { x--; } } } for (int y = 0; y < 272; y++) { coulTrouvee[BitmapCpc.Palette[x], y] = 0; } takeDist = !takeDist; cUtil = x; } } if (p.sortPal) { for (x = 0; x < maxPen - 1; x++) { for (int c = x + 1; c < maxPen; c++) { if (lockState[x] == 0 && lockState[c] == 0 && BitmapCpc.Palette[x] > BitmapCpc.Palette[c]) { int tmp = BitmapCpc.Palette[x]; BitmapCpc.Palette[x] = BitmapCpc.Palette[c]; BitmapCpc.Palette[c] = tmp; } } } } }
static void SetPixColTriangle(BitmapCpc dest) { int[,] matTri = new int[4, 4] { { 0, 0, 0, 1 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 1, 0, 0, 0 } }; int index = 0, pos = 0, nb1 = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { if (matTri[i1, i2] == 1) { nb1++; } } } for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { int sr = tabCol[i1].red * (16 - nb1) + tabCol[i2].red * nb1; int sv = tabCol[i1].green * (16 - nb1) + tabCol[i2].green * nb1; int sb = tabCol[i1].blue * (16 - nb1) + tabCol[i2].blue * nb1; tabMelange[pos++] = new RvbColor(sr, sv, sb); } } int choix0 = 0, choix1 = 0; for (int y = 0; y < tailleY; y += 8) { for (int x = 0; x < tailleX; x += 8) { int OldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { bitmap.AddGetPixel(x + 2 * i2 < tailleX ? x + 2 * i2 : x + 1, y + 2 * i1 < tailleY ? y + 2 * i1 : y + 1, ref totR, ref totV, ref totB); } } pos = 0; for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { int Dist = CalcDist(tabMelange[pos].red, tabMelange[pos].green, tabMelange[pos].blue, totR, totV, totB); pos++; if (Dist < OldDist) { choix0 = i1; choix1 = i2; OldDist = Dist; if (Dist == 0) { i1 = i2 = 4; } } } } resultTri[index++] = choix0 + (choix1 << 2); for (int i1 = 0; i1 < 4; i1++) { for (int i2 = 0; i2 < 4; i2++) { dest.SetPixelCpc(x + 2 * i2 < tailleX ? x + 2 * i2 : x + 1, y + 2 * i1 < tailleY ? y + 2 * i1 : y + 1, matTri[i1, i2] == 0 ? choix0 : choix1); } } } } }
static void SetPixCol3(BitmapCpc dest) { int pos = 0; for (int i1 = 0; i1 < MaxCol; i1++) { for (int i2 = 0; i2 < MaxCol; i2++) { for (int i3 = 0; i3 < MaxCol; i3++) { for (int i4 = 0; i4 < MaxCol; i4++) { int sr = tabCol[i1].red + tabCol[i2].red + tabCol[i3].red + tabCol[i4].red; int sv = tabCol[i1].green + tabCol[i2].green + tabCol[i3].green + tabCol[i4].green; int sb = tabCol[i1].blue + tabCol[i2].blue + tabCol[i3].blue + tabCol[i4].blue; tabMelange[pos++] = new RvbColor(sr, sv, sb); } } } } int choix0 = 0, choix2 = 0, choix3 = 0, choix1 = 0; for (int y = 0; y < tailleY; y += 4) { int ynorm = y + 2 < tailleY ? y + 2 : y + 1; for (int x = 0; x < tailleX; x += Tx << 1) { int xnorm = x + Tx < tailleX ? x + Tx : x + 1; int OldDist = 0x7FFFFFFF; int totR = 0, totV = 0, totB = 0; bitmap.GetPixel(x, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(x, ynorm, ref totR, ref totV, ref totB); bitmap.AddGetPixel(xnorm, y, ref totR, ref totV, ref totB); bitmap.AddGetPixel(xnorm, ynorm, ref totR, ref totV, ref totB); pos = 0; for (int i1 = 0; i1 < MaxCol; i1++) { for (int i2 = 0; i2 < MaxCol; i2++) { for (int i3 = 0; i3 < MaxCol; i3++) { for (int i4 = 0; i4 < MaxCol; i4++) { int Dist = CalcDist(tabMelange[pos].red, tabMelange[pos].green, tabMelange[pos].blue, totR, totV, totB); pos++; if (Dist < OldDist) { choix0 = i1; choix1 = i2; choix2 = i3; choix3 = i4; OldDist = Dist; if (Dist == 0) { i1 = i2 = i3 = i4 = MaxCol; } } } } } } dest.SetPixelCpc(x, y, choix0); dest.SetPixelCpc(x, ynorm, choix2); dest.SetPixelCpc(xnorm, y, choix3); dest.SetPixelCpc(xnorm, ynorm, choix1); } } }
static int CalcDist(RvbColor c, int r, int v, int b) { return((c.red > r ? (c.red - r) * K_R : (r - c.red) * K_R) + (c.green > v ? (c.green - v) * K_V : (v - c.green) * K_V) + (c.blue > b ? (c.blue - b) * K_B : (b - c.blue) * K_B)); }
static private RvbColor GetPixel(DirectBitmap source, int xPix, int yPix, int Tx, Param prm, int pct) { RvbColor p = new RvbColor(0); if (prm.lissage) { float r = 0, v = 0, b = 0; for (int i = 0; i < Tx; i++) { p = source.GetPixelColor(xPix + i, yPix); r += p.r; b += p.b; v += p.v; } p.r = (byte)(r / Tx); p.v = (byte)(v / Tx); p.b = (byte)(b / Tx); } else { p = source.GetPixelColor(xPix, yPix); } switch (prm.bitsRVB) { //12 bits (4 bits par composantes) case 12: p.r = (byte)((p.r >> 4) * 17); p.v = (byte)((p.v >> 4) * 17); p.b = (byte)((p.b >> 4) * 17); break; // 9 bits (3 bits par composantes) case 9: p.r = (byte)((p.r >> 5) * 36); p.v = (byte)((p.v >> 5) * 36); p.b = (byte)((p.b >> 5) * 36); break; // 6 bits (2 bits par composantes) case 6: p.r = (byte)((p.r >> 6) * 85); p.v = (byte)((p.v >> 6) * 85); p.b = (byte)((p.b >> 6) * 85); break; } int m1 = (prm.reductPal1 ? 0x11 : 0x00) | (prm.reductPal3 ? 0x22 : 0x00); int m2 = (prm.reductPal2 ? 0xEE : 0xFF) & (prm.reductPal4 ? 0xDD : 0xFF); p.r = MinMaxByte(((p.r | m1) & m2) * prm.pctRed / 100.0); p.v = MinMaxByte(((p.v | m1) & m2) * prm.pctGreen / 100.0); p.b = MinMaxByte(((p.b | m1) & m2) * prm.pctBlue / 100.0); if (p.r != 0 || p.v != 0 || p.b != 0) { float r = tblContrast[p.r]; float v = tblContrast[p.v]; float b = tblContrast[p.b]; if (prm.pctLumi != 100 || prm.pctSat != 100) { SetLumiSat(prm.pctLumi > 100 ? (100 + (prm.pctLumi - 100) * 2) / 100.0F : prm.pctLumi / 100.0F, prm.pctSat / 100.0F, ref r, ref v, ref b); } p.r = MinMaxByte(r); p.v = MinMaxByte(v); p.b = MinMaxByte(b); } // Appliquer la matrice de tramage if (pct > 0) { RvbColor choix = prm.cpcPlus ? new RvbColor((byte)((p.r >> 4) * 17), (byte)((p.v >> 4) * 17), (byte)((p.b >> 4) * 17)) : BitmapCpc.RgbCPC[GetNumColorPixelCpc(prm, p)]; Dither.DoDitherFull(source, xPix, yPix, Tx, p, choix, prm.diffErr); } return(p); }