unsafe private static void SetPDNAlpha(ColorBgra* dstPixel, PhotoshopFile.Layer.Channel alphaChannel, int srcIndex, int maskAlpha) { byte alpha = 255; if (alphaChannel != null) alpha = alphaChannel.ImageData[srcIndex]; if (maskAlpha < 255) alpha = (byte)(alpha * maskAlpha / 255); dstPixel->A = alpha; }
/////////////////////////////////////////////////////////////////////////// unsafe private static void SetPDNColor(ColorBgra* dstPixel, PhotoshopFile.Layer layer, PhotoshopFile.Layer.Channel[] channels, PhotoshopFile.Layer.Channel alphaChannel, int pos) { switch (layer.PsdFile.ColorMode) { case PsdFile.ColorModes.RGB: dstPixel->R = channels[0].ImageData[pos]; dstPixel->G = channels[1].ImageData[pos]; dstPixel->B = channels[2].ImageData[pos]; break; case PsdFile.ColorModes.CMYK: SetPDNColorCMYK(dstPixel, channels[0].ImageData[pos], channels[1].ImageData[pos], channels[2].ImageData[pos], channels[3].ImageData[pos]); break; case PsdFile.ColorModes.Multichannel: SetPDNColorCMYK(dstPixel, channels[0].ImageData[pos], channels[1].ImageData[pos], channels[2].ImageData[pos], 0); break; case PsdFile.ColorModes.Bitmap: byte bwValue = ImageDecoder.GetBitmapValue(channels[0].ImageData, pos); dstPixel->R = bwValue; dstPixel->G = bwValue; dstPixel->B = bwValue; break; case PsdFile.ColorModes.Grayscale: case PsdFile.ColorModes.Duotone: dstPixel->R = channels[0].ImageData[pos]; dstPixel->G = channels[0].ImageData[pos]; dstPixel->B = channels[0].ImageData[pos]; break; case PsdFile.ColorModes.Indexed: int index = (int)channels[0].ImageData[pos]; dstPixel->R = (byte)layer.PsdFile.ColorModeData[index]; dstPixel->G = layer.PsdFile.ColorModeData[index + 256]; dstPixel->B = layer.PsdFile.ColorModeData[index + 2 * 256]; break; case PsdFile.ColorModes.Lab: SetPDNColorLab(dstPixel, channels[0].ImageData[pos], channels[1].ImageData[pos], channels[2].ImageData[pos]); break; } }
private Layer AddNewLayer(PsdFile psdFile, int index) { PhotoshopFile.Layer psdLayer = new PhotoshopFile.Layer(psdFile) { BlendModeKey = "norm", Visible = true, // Set layer metadata Rect = new System.Drawing.Rectangle(0, 0, psdFile.Columns, psdFile.Rows), Name = "Layer " + index, Opacity = 255 }; psdLayer.Visible = true; psdLayer.MaskData = new PhotoshopFile.Layer.Mask(psdLayer); psdLayer.BlendingRangesData = new PhotoshopFile.Layer.BlendingRanges(psdLayer); // Preserve Unicode layer name as Additional Layer Information var luniLayerInfo = new PhotoshopFile.Layer.AdjustmentLayerInfo("luni"); var luniData = Encoding.BigEndianUnicode.GetBytes("\u0000\u0000" + psdLayer.Name); Util.SetBigEndianInt32(luniData, 0, psdLayer.Name.Length); luniLayerInfo.Data = luniData; psdLayer.AdjustmentInfo.Add(luniLayerInfo); // Store channel metadata int layerSize = psdLayer.Rect.Width * psdLayer.Rect.Height; for (int i = -1; i < 3; i++) { PhotoshopFile.Layer.Channel ch = new PhotoshopFile.Layer.Channel((short)i, psdLayer) { ImageCompression = ImageCompression.Rle, ImageData = new byte[layerSize] }; } return(psdLayer); }
public CompressChannelContext(PhotoshopFile.Layer.Channel ch) { this.ch = ch; }
public DecompressChannelContext(PhotoshopFile.Layer.Channel ch) { this.ch = ch; }
public static void SaveLayerPixels(BitmapLayer layer, PsdFile psdFile, Document input, PhotoshopFile.Layer psdLayer, PsdSaveConfigToken psdToken) { Surface surface = layer.Surface; int rectLeft = input.Width; int rectTop = input.Height; int rectRight = 0; int rectBottom = 0; // Determine the real size of this layer, i.e., the smallest rectangle // that includes all all non-invisible pixels unsafe { for (int y = 0; y < psdFile.Rows; y++) { int rowIndex = y * psdFile.Columns; ColorBgra *srcRow = surface.GetRowAddress(y); ColorBgra *srcPixel = srcRow; for (int x = 0; x < psdFile.Columns; x++) { int pos = rowIndex + x; // Found a non-transparent pixel, potentially increase the size of the rectangle if (srcPixel->A > 0) { // Expand the rectangle if (x < rectLeft) { rectLeft = x; } if (x > rectRight) { rectRight = x; } if (y < rectTop) { rectTop = y; } if (y > rectBottom) { rectBottom = y; } } srcPixel++; } } } psdLayer.Rect = new Rectangle(rectLeft, rectTop, rectRight - rectLeft + 1, rectBottom - rectTop + 1); psdLayer.Name = layer.Name; psdLayer.Opacity = layer.Opacity; psdLayer.Visible = layer.Visible; psdLayer.MaskData = new PhotoshopFile.Layer.Mask(psdLayer); psdLayer.BlendingRangesData = new PhotoshopFile.Layer.BlendingRanges(psdLayer); int layerSize = psdLayer.Rect.Width * psdLayer.Rect.Height; for (int i = -1; i < 3; i++) { PhotoshopFile.Layer.Channel ch = new PhotoshopFile.Layer.Channel((short)i, psdLayer); ch.ImageCompression = psdToken.RleCompress ? ImageCompression.Rle : ImageCompression.Raw; ch.ImageData = new byte[layerSize]; } var channels = psdLayer.ChannelsArray; var alphaChannel = psdLayer.AlphaChannel; unsafe { int rowIndex = 0; for (int y = 0; y < psdLayer.Rect.Height; y++) { ColorBgra *srcRow = surface.GetRowAddress(y + psdLayer.Rect.Top); ColorBgra *srcPixel = srcRow + psdLayer.Rect.Left; for (int x = 0; x < psdLayer.Rect.Width; x++) { int pos = rowIndex + x; channels[0].ImageData[pos] = srcPixel->R; channels[1].ImageData[pos] = srcPixel->G; channels[2].ImageData[pos] = srcPixel->B; alphaChannel.ImageData[pos] = srcPixel->A; srcPixel++; } rowIndex += psdLayer.Rect.Width; } } }