//----------------------------------------------------- void Start() { tex = new Texture2D(0,0,TextureFormat.RGB24, false); tex = (Texture2D) GameObject.Find("Background/backgroundImage").GetComponent<GUITexture>().texture; width = tex.width; height = tex.height; image = new image(width, height); image.setPixels(tex); // Générer le tableau mask = new bool[width,height]; // Note : les bool sont initialisés à false par défaut for(int i=0; i<m_inputMask.Count; i++) mask[m_inputMask[i].GetX(), m_inputMask[i].GetY()] = true; // for(int y=0;y<height;y++) // Texture2D remplacée par une liste de MaskPix // for(int x=0;x<width;x++) // mask[x,y]=(masktex.GetPixel(x,y).r == 1); // DestroyImmediate(masktex); // TODO libérer la mémoire de masktex // for(int y=0;y<height;y++) // KS : commenté, aucune différence apparente. // { // for(int x=0;x<width;x++) // { // if (mask[x,y]) // { // image.set_r(255,x,y); // image.set_g(0,x,y); // image.set_b(0,x,y); // } // } // } Debug.Log("mask created"); // display input with red area // GameObject.Find("/Background/backgroundImage").guiTexture.texture = image.getTexture(); // KS : utile pour debug seulement inpainting = new Inpaint(image, mask, 2); // initialisation inpainting scaleLevel = inpainting.maxlevel-1; Debug.Log(scaleLevel+" levels"); }
//----------------------------------------------------- public static void SynthesizeFromBaseTex(Texture2D baseTex) { image i = new image(c_sampleSize, c_sampleSize); i.setPixels(baseTex); // -- Synthétisation de la texture à partir de l'échantillon -- TextureSynthesizer ts = new TextureSynthesizer(128, 128); i = ts.synthesize(i); s_synthTex = i.getTextureRGB(); s_synthTex.Apply(); // byte[] bytes = m_synthTex.EncodeToPNG(); // Sauvegarde en fichier // System.IO.File.WriteAllBytes(Application.dataPath+"/Resources/grass/synth/grassSynth0.png", bytes); // -- Enregistrer la texture et l'appliquer aux plans de gazon -- GameObject.Find("grassSkybox").GetComponent<GrassHandler>().AddSynthTex(s_synthTex, baseTex, true); // -- Modifier l'interface (devrait être fait dans le contrôleur) -- // GameObject.Find("MainScene").GetComponent<GUIMenuMain>().SetHideAll(false); // GameObject.Find("mainCam").transform.camera.cullingMask = m_camMaskBk; GameObject.Find("MainScene").GetComponent<PleaseWaitUI>().SetDisplayIcon(false); }
/** * @param image * @return out3 */ public image synthesize(image img) { // BufferedImage copie = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); // copie = CubeImage.getAsCopy(image); image copie = new image(img); _in = duplicateSample(copie); //Nb de patch par ligne et par colonne _nbPatchPerLine = _widthFinalTexture / (_patchSize-_widthBorder) +1; _nbPatchPerColumn = _heightFinalTexture / (_patchSize-_widthBorder) +1; _nbPatchPasted = 1; nbLinesDone = 0; _widthAnalysis = _in.Width() - _patchSize; _heightAnalysis = _in.Height() - _patchSize; //Initialisation de Out // BufferedImage out = new BufferedImage((_nbPatchPerLine)*(_patchSize-_widthBorder)+_widthBorder, (_nbPatchPerColumn)*(_patchSize-_widthBorder)+_widthBorder, BufferedImage.TYPE_INT_ARGB); image outImg = new image((_nbPatchPerLine)*(_patchSize-_widthBorder)+_widthBorder, (_nbPatchPerColumn)*(_patchSize-_widthBorder)+_widthBorder); System.Random r = new System.Random(); // int x = r.nextInt(_widthAnalysis); // int y = r.nextInt(_heightAnalysis); int x = r.Next(_widthAnalysis); int y = r.Next(_heightAnalysis); // BufferedImage firstPatch = _in.getSubimage(x, y, _patchSize, _patchSize); image first_patch = _in.getSubImage(x, y, _patchSize, _patchSize); // out.getGraphics().drawImage(firstPatch, 0, 0, null); outImg.setPixels(first_patch); analyseIn(_in); for(int i=0; i<_nbPatchPerLine-1; i++) firstLine(_in, outImg); for(int i=0; i<_nbPatchPerColumn-1; i++) { nbLinesDone++; firstPatch(_in, outImg); _nbPatchPasted = 1; for(int k=0; k<_nbPatchPerLine-1; k++) otherLine(_in, outImg); } // out = out.getSubimage(0, 0, _widthFinalTexture, _heightFinalTexture); outImg = outImg.getSubImage(0, 0, _widthFinalTexture, _heightFinalTexture); // BufferedImage out2 = new BufferedImage(2*_widthFinalTexture, 2*_heightFinalTexture, BufferedImage.TYPE_INT_ARGB); image out2 = new image(2*_widthFinalTexture, 2*_heightFinalTexture); // out2.getGraphics().drawImage(out, 0, 0, null); out2.setPixels(outImg); // out2.getGraphics().drawImage(out, _widthFinalTexture, 0, null); out2.setPixels(outImg, _widthFinalTexture, 0); // out2.getGraphics().drawImage(out, 0, _heightFinalTexture, null); out2.setPixels(outImg, 0, _heightFinalTexture); // out2.getGraphics().drawImage(out, _widthFinalTexture, _heightFinalTexture, null); out2.setPixels(outImg, _widthFinalTexture, _heightFinalTexture); // BufferedImage out3 = new BufferedImage(4*_widthFinalTexture, 4*_heightFinalTexture, BufferedImage.TYPE_INT_ARGB); image out3 = new image(4*_widthFinalTexture, 4*_heightFinalTexture); // out3.getGraphics().drawImage(out2, 0, 0, null);//out2 out3.setPixels(out2, 0, 0);//out2 // out3.getGraphics().drawImage(out2, 2*_widthFinalTexture, 0, null); out3.setPixels(out2, 2*_widthFinalTexture, 0); // out3.getGraphics().drawImage(out2, 0, 2*_heightFinalTexture, null); out3.setPixels(out2, 0, 2*_heightFinalTexture); // out3.getGraphics().drawImage(out2, 2*_widthFinalTexture, 2*_heightFinalTexture, null); out3.setPixels(out2, 2*_widthFinalTexture, 2*_heightFinalTexture); return out3; }
/** * Les lignes suivantes * @param in * @param out */ private void otherLine(image imgIn, image imgOut) { int[] rgbOutH = new int[_widthBorder*_heightBorder]; //Pour les bords du haut int[] rgbOutW = new int[_widthBorder*_heightBorder]; int[] rgbOutHD = new int[_widthBorder*_heightBorder]; //Tableau qui contiendra toutes les distances (en se positionnant en chaque point de In) float[] tabDistanceH = new float[_widthAnalysis*_heightAnalysis]; float[] tabDistanceW = new float[_widthAnalysis*_heightAnalysis]; float[] tabDistanceHD = new float[_widthAnalysis*_heightAnalysis]; //Liste qui contiendra les index (numeros de pixels) dont la distance avec le dernier patch collé est //inferieure à la distance max float[] tabDistInf = new float[200]; int[] tabDistInfIndex = new int[tabDistInf.Length]; for (int i = 0; i < tabDistInf.Length; i++) { tabDistInf[i] = float.MaxValue; tabDistInfIndex[i] = -1; } //Les valeurs rgb du bord de _out (à droite) // out.getRGB(((_nbPatchPasted)*(_patchSize-_widthBorder)), nbLinesDone*(_patchSize-_widthBorder), _widthBorder, _heightBorder, rgbOutH, 0, _widthBorder); imgOut.getRGB(rgbOutH, ((_nbPatchPasted)*(_patchSize-_widthBorder)), nbLinesDone*(_patchSize-_widthBorder), _widthBorder, _heightBorder); // out.getRGB(0, nbLinesDone*(_patchSize-_widthBorder), _widthBorder, _heightBorder, rgbOutHD, 0, _widthBorder); imgOut.getRGB(rgbOutHD, 0, nbLinesDone*(_patchSize-_widthBorder), _widthBorder, _heightBorder); //Les valeurs rgb du bord de out (en bas) // out.getRGB((_nbPatchPasted)*(_patchSize-_widthBorder), nbLinesDone*(_patchSize-_widthBorder), _heightBorder, _widthBorder, rgbOutW, 0, _heightBorder); imgOut.getRGB(rgbOutW, (_nbPatchPasted)*(_patchSize-_widthBorder), nbLinesDone*(_patchSize-_widthBorder), _heightBorder, _widthBorder); float dMax = 0; if(_nbPatchPasted == _nbPatchPerLine-1) dMax = get_dMax(rgbOutH) + get_dMax(rgbOutW) + get_dMax(rgbOutHD); else dMax = get_dMax(rgbOutH) + get_dMax(rgbOutW); int index = 0; int distMin = int.MaxValue; int indexMin = int.MaxValue; //Parcours de l image (moins les deux bords en bas et à droite) for (int i=0; i<_widthAnalysis*_heightAnalysis; i+=_pasBalayage) { //L ensemble des distances en positionnant le patch sur chaque pixel de l image tabDistanceH[index] = distance(_tabInH[index], rgbOutH); tabDistanceHD[index] = distance(_tabInHD[index], rgbOutHD); tabDistanceW[index] = distance(_tabInW[index], rgbOutW); //On fait la somme des deux distances tabDistanceW[index] += tabDistanceH[index]; if(_nbPatchPasted == _nbPatchPerLine-1) tabDistanceW[index] += tabDistanceHD[index]; if(tabDistanceW[index] < dMax) { float distmax = -1; int indexTabdistInf = -1; for(int k=0; k<tabDistInf.Length; k++) { if(tabDistanceW[index] < tabDistInf[k]) { if(tabDistInf[k] > distmax) { distmax = tabDistInf[k]; indexTabdistInf = k; } } } if(indexTabdistInf!=-1) { tabDistInfIndex[indexTabdistInf] = index; tabDistInf[indexTabdistInf] = tabDistanceW[index]; } } //Distance min if(tabDistanceW[index]<distMin) { distMin = (int)tabDistanceW[index]; indexMin = index; } index=index+_pasBalayage; } //On ajoute la plus petite distance si aucune n etait inférieure à dMax int l = 0; while(l<tabDistInf.Length && tabDistInfIndex[l]!=-1) l++; if(tabDistInf[0]==float.MaxValue) //tableau vide { tabDistInf[0] = distMin; tabDistInfIndex[0] = indexMin; l = 1; } //Un index dans la liste des distance inférieures au seuil (aleatoirement) System.Random r = new System.Random(); int random = r.Next(l); //On copie le patch choisi aleatoirement dans l image out // Graphics2D g2d = (Graphics2D)out.getGraphics(); //Le patch qu on colle dans Out image patch = null; patch = imgIn.getSubImage((tabDistInfIndex[random]%_widthAnalysis), tabDistInfIndex[random]/_widthAnalysis, _patchSize, _patchSize); //Le tableau de pix du bord du patch int[] rgbPatchBorderH = new int[_patchSize*_patchSize]; int[] rgbPatchBorderW = new int[_patchSize*_patchSize]; // patch.getRGB(0, 0, _widthBorder, _heightBorder, rgbPatchBorderH, 0, _widthBorder); patch.getRGB(rgbPatchBorderH, 0, 0, _widthBorder, _heightBorder); // patch.getRGB(0, 0, _heightBorder, _widthBorder, rgbPatchBorderW, 0, _heightBorder); patch.getRGB(rgbPatchBorderW, 0, 0, _heightBorder, _widthBorder); //On colle le patch par dessus le dernier patch collé dans Out // g2d.drawImage(patch,_nbPatchPasted*(_patchSize-_widthBorder), nbLinesDone*(_patchSize-_widthBorder), null); imgOut.setPixels(patch, _nbPatchPasted*(_patchSize-_widthBorder), nbLinesDone*(_patchSize-_widthBorder)); //On arrange la liaison entre les deux patch // out = borderH(rgbOutH, rgbPatchBorderH, out); imgOut = borderH(rgbOutH, rgbPatchBorderH, imgOut); // out = borderW(rgbOutW, rgbPatchBorderW, out, false); imgOut = borderW(rgbOutW, rgbPatchBorderW, imgOut, false); _nbPatchPasted++; }
//----------------------------------------------------- // Fonction qui génère une image 4 fois plus grande que l image d entrée // en effectuant des miroirs par rapport à l image d entrée // @param image L'image d entrée // @return duplicateImage L'image dupliquée // private BufferedImage duplicateSample(BufferedImage image) private image duplicateSample(image img) { int[] rgb = new int[(_sampleSize/2)*(_sampleSize/2)]; // rgb = image.getRGB(_sampleSize/2, _sampleSize/2, rgb, 0, _sampleSize/2); rgb = img.getRGB(rgb); rgb = removeArtifacts(rgb); // enlève les pixels trop eloignés de la moyenne du sample // image.setRGB(0, 0, _sampleSize/2, _sampleSize/2, rgb, 0, _sampleSize/2); img.setRGB(rgb); // image sans artefacts // -- Miroir par rap à Y -- // BufferedImage _inYmirror = new BufferedImage(_sampleSize/2, _sampleSize/2, BufferedImage.TYPE_INT_ARGB); image _inYmirror = new image(img); // Copie _inYmirror.MirrorY(); // BufferedImage _in4 = new BufferedImage(2*image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); image _in4 = new image(2*img.Width(), img.Height()); // _in4.getGraphics().drawImage(image, 0, 0, null); _in4.setPixels(img); // _in4.getGraphics().drawImage(_inYmirror, _in4.getWidth()/2, 0, null); _in4.setPixels(_inYmirror, _in4.Width()/2, 0); // TODO Vérifier si le résultat est correct // -- Miroir par rap à X -- // BufferedImage in5 = new BufferedImage(_sampleSize, _sampleSize/2, BufferedImage.TYPE_INT_ARGB); image in5 = new image(_in4); in5.MirrorX(); // BufferedImage duplicateImage = new BufferedImage(_sampleSize, _sampleSize, BufferedImage.TYPE_INT_ARGB); image duplicateImage = new image(_sampleSize, _sampleSize); // duplicateImage.getGraphics().drawImage(_in4, 0, 0, null); duplicateImage.setPixels(_in4); // duplicateImage.getGraphics().drawImage(in5, 0, _sampleSize/2, null); duplicateImage.setPixels(in5, 0, _sampleSize/2); return duplicateImage; }