public void TestMake() { Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); var resPath = Path.Combine(Environment.CurrentDirectory, @"..\..\Res"); var path = Path.Combine(resPath, "test.txt"); PsdFile psd = new PsdFile { Width = 600, Height = 600, Resolution = new ResolutionInfo { HeightDisplayUnit = ResolutionInfo.Unit.Centimeters, WidthDisplayUnit = ResolutionInfo.Unit.Centimeters, HResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, VResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, HDpi = new UFixed16_16(0, 350), VDpi = new UFixed16_16(0, 350) }, ImageCompression = ImageCompression.Rle }; psd.ImageResources.Add(new XmpResource("") { XmpMetaString = File.ReadAllText(path) }); psd.Save(Path.Combine(resPath, "xmp.psd"), Encoding.UTF8); }
/// <summary> /// PSDファイルをトップレベルのレイヤグループ単位で分割します /// </summary> /// <param name="outdir_prefix">出力先フォルダのプリフィクス</param> /// <param name="split_anime_layer">アニメーションレイヤグループ(「@」から始まるレイヤグループ)の展開を許可します</param> public void Split() { //出力先ディレクトリを作成する string out_dir; out_dir = Path.Combine(Path.GetDirectoryName(InputFilePath), OutputDirPrefix + Path.GetFileName(InputFilePath)); out_dir = Path.GetFullPath(out_dir); if (!Directory.Exists(out_dir)) { Directory.CreateDirectory(out_dir); } //PSDを分解する List <KeyValuePair <string, List <Layer> > > splitted_layers = SplitPsd(); //分解したPSDそれぞれ保存する for (int i = 0; i < splitted_layers.Count; i++) { string name = splitted_layers[i].Key; List <Layer> layers = splitted_layers[i].Value; PsdFile psd_out = MakePsd(InputPsdFile, layers); string out_filename = string.Format("{0}-{1}.psd", Path.GetFileNameWithoutExtension(InputFilePath), name); Array.ForEach(Path.GetInvalidFileNameChars(), x => { out_filename = out_filename.Replace(x, '_'); }); psd_out.Save(Path.Combine(out_dir, out_filename), Encoding.UTF8); } }
public static void Save(Document input, Stream output, PsdSaveConfigToken psdToken, Surface scratchSurface, ProgressEventHandler progressCallback) { var psdVersion = ((input.Height > 30000) || (input.Width > 30000)) ? PsdFileVersion.PsbLargeDocument : PsdFileVersion.Psd; var psdFile = new PsdFile(psdVersion); psdFile.RowCount = input.Height; psdFile.ColumnCount = input.Width; // We only save in RGBA format, 8 bits per channel, which corresponds to // Paint.NET's internal representation. psdFile.ChannelCount = 4; psdFile.ColorMode = PsdColorMode.RGB; psdFile.BitDepth = 8; psdFile.Resolution = GetResolutionInfo(input); psdFile.ImageCompression = psdToken.RleCompress ? ImageCompression.Rle : ImageCompression.Raw; // Treat the composite image as another layer when reporting progress. var progress = new ProgressNotifier(progressCallback); var percentPerLayer = percentStoreImages / (input.Layers.Count + 1); // Render the composite image. This operation is parallelized within // Paint.NET using its own private thread pool. using (var ra = new RenderArgs(scratchSurface)) { input.Flatten(scratchSurface); progress.Notify(percentRenderComposite); } // Delegate to store the composite Action storeCompositeAction = () => { // Allocate space for the composite image data int imageSize = psdFile.RowCount * psdFile.ColumnCount; for (short i = 0; i < psdFile.ChannelCount; i++) { var channel = new Channel(i, psdFile.BaseLayer); channel.ImageData = new byte[imageSize]; channel.ImageCompression = psdFile.ImageCompression; psdFile.BaseLayer.Channels.Add(channel); } var channelsArray = psdFile.BaseLayer.Channels.ToIdArray(); StoreLayerImage(channelsArray, channelsArray[3], scratchSurface, psdFile.BaseLayer.Rect); progress.Notify(percentPerLayer); }; // Delegate to store the layers Action storeLayersAction = () => { // LayerList is an ArrayList, so we have to cast to get a generic // IEnumerable that works with LINQ. var pdnLayers = input.Layers.Cast <BitmapLayer>(); // Create folders/groups before actual image data will be saved. var layerInfos = PrepareLayers(pdnLayers, psdToken.SaveLayers); var psdLayers = layerInfos.AsParallel().AsOrdered().Select(pdnLayer => { var psdLayer = new PhotoshopFile.Layer(psdFile); StoreLayer(pdnLayer, psdLayer, psdToken); progress.Notify(percentPerLayer); return(psdLayer); }); psdFile.Layers.AddRange(psdLayers); }; // Process composite and layers in parallel Parallel.Invoke(storeCompositeAction, storeLayersAction); psdFile.Save(output, Encoding.Default); }
static private void UpdatePsd(FileInfo fileInfo, Dictionary <string, Color> convertMap) { Console.Out.WriteLine("Start Convert " + fileInfo.FullName); var fileStream = new FileStream(fileInfo.FullName, FileMode.Open); if (fileStream == null) { Console.Out.WriteLine("Paramter Error, Skip"); return; } var psdFile = new PsdFile(fileStream, new LoadContext()); fileStream.Close(); foreach (Layer layr in psdFile.Layers) { var layName = layr.Name.ToUpper(); try { var findKey = convertMap.Single(x => layName.Contains(x.Key)); var color = findKey.Value; var vscg = layr.AdditionalInfo.SingleOrDefault(x => x.Key == "vscg"); var solidColor = layr.AdditionalInfo.SingleOrDefault(x => x.Key == "SoCo"); //var tysh = layr.AdditionalInfo.SingleOrDefault(x => x.Key == "TySh"); if (solidColor == null /*&& tysh == null*/ && vscg == null) { ConsoleColor oldColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine("Convert Error : " + fileInfo.FullName); Console.ForegroundColor = oldColor; return; } if (vscg != null) { solidColor = vscg; } if (solidColor != null) { PhotoshopFile.PsdDescriptor eff = new PhotoshopFile.PsdDescriptor(CreateReadStream(solidColor)); double red = color.R; double green = color.G; double blue = color.B; byte[] redBuffer, greenBuffer, blueBuffer; unsafe { BinaryReverseReader.SwapBytes((byte *)&red, 8); redBuffer = ConvertDoubleToByteArray(red); BinaryReverseReader.SwapBytes((byte *)&green, 8); greenBuffer = ConvertDoubleToByteArray(green); BinaryReverseReader.SwapBytes((byte *)&blue, 8); blueBuffer = ConvertDoubleToByteArray(blue); } long redOffset = 0, greenOffset = 0, blueOffset = 0; GetPSDColorOffset(eff, ref redOffset, ref greenOffset, ref blueOffset); BinaryReverseWriter writer = CreateWriteStream(solidColor); writer.Seek((int)redOffset, SeekOrigin.Begin); writer.Write(redBuffer); writer.Seek((int)greenOffset, SeekOrigin.Begin); writer.Write(greenBuffer); writer.Seek((int)blueOffset, SeekOrigin.Begin); writer.Write(blueBuffer); } //else if (tysh != null) //{ // PhotoshopFile.LayerResources.TypeToolTyShPH6 txt = new PhotoshopFile.LayerResources.TypeToolTyShPH6(CreateReadStream(tysh)); // Dictionary<string, object> d = txt.StylesheetReader.GetStylesheetDataFromLongestRun(); // BinaryReverseWriter writer = CreateWriteStream(tysh); // //writer.Seek((int)redOffset, SeekOrigin.Begin); // //writer.Write(redBuffer); // //writer.Seek((int)greenOffset, SeekOrigin.Begin); // //writer.Write(greenBuffer); // //writer.Seek((int)blueOffset, SeekOrigin.Begin); // //writer.Write(blueBuffer); //} } catch { } } psdFile.Save(fileInfo.DirectoryName + "\\_" + fileInfo.Name, Encoding.Default); Console.Out.WriteLine("Convert Finished, Save to " + fileInfo.DirectoryName + "\\_" + fileInfo.Name, Encoding.Default); }
private static void ExportMapSafe(String mapName) { try { String relativePath = FieldMap.GetMapResourcePath(mapName); String outputDirectory = Path.Combine(Configuration.Export.Path, relativePath); if (Directory.Exists(outputDirectory)) { Log.Warning($"Export was not skipped because kostyli"); //Log.Warning($"[FieldSceneExporter] Export was skipped bacause a directory already exists: [{outputDirectory}]."); //return; } Log.Message("[FieldSceneExporter] Exporting [{0}]...", mapName); BGSCENE_DEF scene = new BGSCENE_DEF(true); scene.LoadEBG(null, relativePath, mapName); //String directoryPath = Path.GetDirectoryName(outputPath); Directory.CreateDirectory(outputDirectory); Texture2D atlasTexture = TextureHelper.CopyAsReadable(scene.atlas); Int32 factor = (Int32)scene.SPRITE_W / 16; Int32 textureWidth = (Int32)(scene.overlayList.SelectMany(s => s.spriteList).Max(s => s.offY * factor) + scene.SPRITE_H); Int32 textureHeight = (Int32)(scene.overlayList.SelectMany(s => s.spriteList).Max(s => s.offX * factor) + scene.SPRITE_W); using (Stream output = File.Create(outputDirectory + "test.psd")) { PsdFile file = new PsdFile(); file.BitDepth = 8; file.ChannelCount = 4; file.ColorMode = PsdColorMode.Rgb; file.RowCount = textureWidth; file.ColumnCount = textureHeight; file.Resolution = new ResolutionInfo { Name = "ResolutionInfo ", HDpi = new UFixed1616(72, 0), HResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, HeightDisplayUnit = ResolutionInfo.Unit.Centimeters, VDpi = new UFixed1616(72, 0), VResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, WidthDisplayUnit = ResolutionInfo.Unit.Centimeters }; file.BaseLayer.Name = "Base"; for (Int16 i = 0; i < 4; i++) { Channel channel = new Channel(i, file.BaseLayer); channel.ImageCompression = file.ImageCompression; channel.Length = file.RowCount * Util.BytesPerRow(file.BaseLayer.Rect.Size, file.BitDepth); channel.ImageData = new Byte[channel.Length]; file.BaseLayer.Channels.Add(channel); } file.BaseLayer.Channels.Last().ID = -1; for (Int32 index = scene.overlayList.Count - 1; index >= 0; index--) //scene.overlayList.Count { BGOVERLAY_DEF overlay = scene.overlayList[index]; String outputPath = outputDirectory + $"Overlay{index}.png"; ExportOverlayTest(overlay, atlasTexture, outputPath, scene, file); //return; } file.Save(output, Encoding.UTF8); } //TextureHelper.WriteTextureToFile(TextureHelper.CopyAsReadable(scene.atlas), outputPath); Log.Message("[FieldSceneExporter] Exporting completed successfully."); } catch (Exception ex) { Log.Error(ex, "[FieldSceneExporter] Failed to export map [{0}].", mapName); } }
protected override void OnSave(Document input, System.IO.Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback) { PsdSaveConfigToken psdToken = (PsdSaveConfigToken)token; PsdFile psdFile = new PsdFile(); //----------------------------------------------------------------------- psdFile.Rows = input.Height; psdFile.Columns = input.Width; // we have an Alpha channel which will be saved, // we have to add this to our image resources psdFile.Channels = 4; // for now we oly save the images as RGB psdFile.ColorMode = PsdFile.ColorModes.RGB; psdFile.Depth = 8; //----------------------------------------------------------------------- // no color mode Data //----------------------------------------------------------------------- ResolutionInfo resInfo = new ResolutionInfo(); resInfo.HeightUnit = ResolutionInfo.Unit.In; resInfo.WidthUnit = ResolutionInfo.Unit.In; if (input.DpuUnit == MeasurementUnit.Inch) { resInfo.HResUnit = ResolutionInfo.ResUnit.PxPerInch; resInfo.VResUnit = ResolutionInfo.ResUnit.PxPerInch; resInfo.HRes = (short)input.DpuX; resInfo.VRes = (short)input.DpuY; } else { resInfo.HResUnit = ResolutionInfo.ResUnit.PxPerCent; resInfo.VResUnit = ResolutionInfo.ResUnit.PxPerCent; resInfo.HRes = (short)(input.DpuX / 2.54); resInfo.VRes = (short)(input.DpuY / 2.54); } psdFile.Resolution = resInfo; //----------------------------------------------------------------------- psdFile.ImageCompression = psdToken.RleCompress ? ImageCompression.Rle : ImageCompression.Raw; int size = psdFile.Rows * psdFile.Columns; psdFile.ImageData = new byte[psdFile.Channels][]; for (int i = 0; i < psdFile.Channels; i++) { psdFile.ImageData[i] = new byte[size]; } using (RenderArgs ra = new RenderArgs(scratchSurface)) { input.Flatten(scratchSurface); } unsafe { for (int y = 0; y < psdFile.Rows; y++) { int rowIndex = y * psdFile.Columns; ColorBgra *srcRow = scratchSurface.GetRowAddress(y); ColorBgra *srcPixel = srcRow; for (int x = 0; x < psdFile.Columns; x++) { int pos = rowIndex + x; psdFile.ImageData[0][pos] = srcPixel->R; psdFile.ImageData[1][pos] = srcPixel->G; psdFile.ImageData[2][pos] = srcPixel->B; psdFile.ImageData[3][pos] = srcPixel->A; srcPixel++; } } } PaintDotNet.Threading.PrivateThreadPool threadPool = new PaintDotNet.Threading.PrivateThreadPool(); foreach (BitmapLayer layer in input.Layers) { PhotoshopFile.Layer psdLayer = new PhotoshopFile.Layer(psdFile); BlendOpToBlendModeKey(layer.BlendOp, psdLayer); SaveLayerPixelsContext slc = new SaveLayerPixelsContext(layer, psdFile, input, psdLayer, psdToken); WaitCallback waitCallback = new WaitCallback(slc.SaveLayer); threadPool.QueueUserWorkItem(waitCallback); } threadPool.Drain(); psdFile.Save(output); }
public void ToBMP(string path) { int width = MaxX / (DIAMETER * 2) - MinX / (DIAMETER * 2); int height = MaxY / (DIAMETER * 2) - MinY / (DIAMETER * 2); int depth = MaxZ - MinZ; PsdFile psdFile = new PsdFile() { //----------------------------------------------------------------------- Rows = height, Columns = width, // We only save in 8 bits per channel RGBA format, which corresponds to // Paint.NET's internal representation. Channels = 4, ColorMode = PsdColorMode.RGB, Depth = 8 }; //----------------------------------------------------------------------- // No color mode data is necessary for RGB //----------------------------------------------------------------------- ResolutionInfo resInfo = new ResolutionInfo() { HeightDisplayUnit = ResolutionInfo.Unit.In, WidthDisplayUnit = ResolutionInfo.Unit.In, HResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, VResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, HDpi = new UFixed16_16(72), VDpi = new UFixed16_16(72) }; psdFile.Resolution = resInfo; psdFile.ImageCompression = ImageCompression.Rle; //----------------------------------------------------------------------- // Set document image data from the fully-rendered image //----------------------------------------------------------------------- int imageSize = psdFile.Rows * psdFile.Columns; psdFile.Layers.Clear(); for (short i = 0; i < psdFile.Channels; i++) { var channel = new Layer.Channel(i, psdFile.BaseLayer) { ImageData = new byte[imageSize], ImageCompression = psdFile.ImageCompression }; } AddNewLayer(psdFile, 0); var alpha = psdFile.Layers[0].AlphaChannel.ImageData; for (int i = 0; i < psdFile.Rows * psdFile.Columns; i++) { alpha[i] = 255; } AddNewLayer(psdFile, 1); for (int y = MinY; y <= MaxY - (DIAMETER * 2); y += (DIAMETER * 2)) { for (int x = MinX; x <= MaxX - (DIAMETER * 2); x += (DIAMETER * 2)) { int hash = CalcHash((short)x, (short)y); try { if (values.ContainsKey(hash)) { var points = (from p in values[hash].Keys orderby p descending select p).ToArray(); for (int index = 0; index < points.Length; index++) { int c = (int)((((float)points[index] - MinZ) / depth) * 250 + 5); int x2 = (x - MinX) / (DIAMETER * 2); int y2 = (y - MinY) / (DIAMETER * 2); if (index >= psdFile.Layers.Count - 1) { AddNewLayer(psdFile, index + 1); } int pos = x2 + width * y2; var rgb = psdFile.Layers[index + 1].ChannelsArray; var alphaCh = psdFile.Layers[index + 1].AlphaChannel; rgb[0].ImageData[pos] = (byte)c; rgb[1].ImageData[pos] = (byte)c; rgb[2].ImageData[pos] = (byte)c; alphaCh.ImageData[pos] = 255; } } } catch { } } } Layer l = psdFile.Layers[0]; psdFile.Layers.RemoveAt(0); psdFile.Layers.Reverse(); psdFile.Layers.Insert(0, l); psdFile.Save(path); psdFile = null; }
private void OnSaveClick(object sender, EventArgs e) { if (m_fileStructure.Nodes.Count == 0) { return; } PsdFile psdFileSrc = (PsdFile)m_fileStructure.Nodes[0].Tag; PsdFile psdFile = new PsdFile(); //----------------------------------------------------------------------- psdFile.Rows = psdFileSrc.Rows; psdFile.Columns = psdFileSrc.Columns; // we have an Alpha channel which will be saved, // we have to add this to our image resources psdFile.Channels = 3;// 4; // for now we oly save the images as RGB psdFile.ColorMode = PsdFile.ColorModes.RGB; psdFile.Depth = 8; //----------------------------------------------------------------------- // no color mode Data //----------------------------------------------------------------------- psdFile.ImageResources.Clear(); psdFile.ImageResources.AddRange(psdFileSrc.ImageResources.ToArray()); //----------------------------------------------------------------------- int size = psdFile.Rows * psdFile.Columns; psdFile.ImageData = new byte[psdFile.Channels][]; for (int i = 0; i < psdFile.Channels; i++) { psdFile.ImageData[i] = new byte[size]; } Bitmap bmp = ImageDecoder.DecodeImage(psdFileSrc); for (int y = 0; y < psdFile.Rows; y++) { int rowIndex = y * psdFile.Columns; for (int x = 0; x < psdFile.Columns; x++) { int pos = rowIndex + x; Color pixelColor = bmp.GetPixel(x, y); psdFile.ImageData[0][pos] = pixelColor.R; psdFile.ImageData[1][pos] = pixelColor.G; psdFile.ImageData[2][pos] = pixelColor.B; //psdFile.ImageData[3][pos] = pixelColor.A; } } //----------------------------------------------------------------------- psdFile.ImageCompression = ImageCompression.Rle; psdFile.Save(Path.Combine(Path.GetDirectoryName(m_fileName.Text), Path.GetFileNameWithoutExtension(m_fileName.Text) + "-saved.psd")); }
private static void ExportMapSafe(String mapName) { try { String relativePath = FieldMap.GetMapResourcePath(mapName); String outputDirectory = Path.Combine(Configuration.Export.Path, relativePath); // TODO: uncomment this when all is well //if (Directory.Exists(outputDirectory)) //{ // Log.Warning($"[FieldSceneExporter] Export was skipped bacause a directory already exists: [{outputDirectory}]."); // //return; //} Log.Message("[FieldSceneExporter] Exporting [{0}]...", mapName); BGSCENE_DEF scene = new BGSCENE_DEF(true); scene.LoadResources(null, relativePath, mapName); //String directoryPath = Path.GetDirectoryName(outputPath); Directory.CreateDirectory(outputDirectory); Texture2D atlasTexture = TextureHelper.CopyAsReadable(scene.atlas); Int32 factor = (Int32)scene.SPRITE_W / 16; Int32 textureWidth = (Int32)(scene.overlayList.SelectMany(s => s.spriteList).Max(s => s.offY * factor) + scene.SPRITE_H); Int32 textureHeight = (Int32)(scene.overlayList.SelectMany(s => s.spriteList).Max(s => s.offX * factor) + scene.SPRITE_W); using (Stream output = File.Create(outputDirectory + "test.psd")) { PsdFile file = new PsdFile(); file.BitDepth = 8; file.ChannelCount = 4; file.ColorMode = PsdColorMode.Rgb; file.RowCount = textureWidth; file.ColumnCount = textureHeight; file.Resolution = new ResolutionInfo { Name = "ResolutionInfo ", HDpi = new UFixed1616(72, 0), HResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, HeightDisplayUnit = ResolutionInfo.Unit.Centimeters, VDpi = new UFixed1616(72, 0), VResDisplayUnit = ResolutionInfo.ResUnit.PxPerInch, WidthDisplayUnit = ResolutionInfo.Unit.Centimeters }; file.BaseLayer.Name = "Base"; for (Int16 i = 0; i < 4; i++) { Channel channel = new Channel(i, file.BaseLayer); channel.ImageCompression = file.ImageCompression; channel.Length = file.RowCount * Util.BytesPerRow(file.BaseLayer.Rect.Size, file.BitDepth); channel.ImageData = new Byte[channel.Length]; file.BaseLayer.Channels.Add(channel); } file.BaseLayer.Channels.Last().ID = -1; for (Int32 index = scene.overlayList.Count - 1; index >= 0; index--) //scene.overlayList.Count { BGOVERLAY_DEF overlay = scene.overlayList[index]; String outputPath = outputDirectory + $"Overlay{index}.png"; ExportOverlay(overlay, atlasTexture, outputPath, scene, file); } // get all languages FieldMapLocalizeAreaTitleInfo info = FieldMapInfo.localizeAreaTitle.GetInfo(mapName); if (info != null) { Int32 startOvrIdx = info.startOvrIdx; Int32 endOvrIdx = info.endOvrIdx; String[] allLanguages = Configuration.Export.Languages; foreach (var language in allLanguages) { BGSCENE_DEF localeScene = new BGSCENE_DEF(scene.GetUseUpscaleFM()); localeScene.LoadLocale(scene, relativePath, mapName, info, language); for (Int32 index = startOvrIdx; index <= endOvrIdx; index++) { BGOVERLAY_DEF overlay = scene.overlayList[index]; String outputPath = outputDirectory + $"Overlay{index}_{language}.png"; ExportOverlay(overlay, atlasTexture, outputPath, scene, file); } } } file.Save(output, Encoding.UTF8); } string strings = $"[PsdSection]\nLayerOrder=name\nReversed = 0"; System.IO.StreamWriter sw = new System.IO.StreamWriter(Path.Combine(outputDirectory, "psd.meta")); sw.WriteLine(strings); sw.Close(); TextureHelper.WriteTextureToFile(atlasTexture, Path.Combine(outputDirectory, "atlas.png")); Log.Message("[FieldSceneExporter] Exporting completed successfully."); } catch (Exception ex) { Log.Error(ex, "[FieldSceneExporter] Failed to export map [{0}].", mapName); } }