Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用c#(通用windows应用程序)将颜色合并到位图中_C# - Fatal编程技术网

使用c#(通用windows应用程序)将颜色合并到位图中

使用c#(通用windows应用程序)将颜色合并到位图中,c#,C#,我有一个.png资源,其中包括下表中所述的需要“着色”的区域(这些是我自己的定义,如果有更好的术语,我应该使用,请随意教我)。我需要根据彩色画笔(例如BGRA=#6572D8FF)为这张图像“上色”,以便 // Input Output // Transparent BGRA=#FFFFFF00 --> #FFFFFF00 // AlphaOnly BGRA=#00000000 --> #6572

我有一个.png资源,其中包括下表中所述的需要“着色”的区域(这些是我自己的定义,如果有更好的术语,我应该使用,请随意教我)。我需要根据彩色画笔(例如BGRA=#6572D8FF)为这张图像“上色”,以便

//                        Input            Output
//    Transparent  BGRA=#FFFFFF00 --> #FFFFFF00
//    AlphaOnly    BGRA=#00000000 --> #6572D800   // Colored area
//    Alpha-Shaded BGRA=#000000aa --> #6572D8aa   // Colored area
//    Solid colors BGRA=#bbggrrFF --> #rrggbbFF
结果图像需要使用以下XAML显示

    <Viewbox Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
        <Grid Height="100" Width="100">
            <Image x:Name="currentImage" />
        </Grid>
    </Viewbox>

将控件放置在红色背景上并指定蓝色画笔,我希望得到底部图像(我只需在原始图像后面放置一个蓝色椭圆即可创建)

不幸的是,我得到了最高的形象。我的透明度丢失了,我希望实现的alpha着色是错误的。任何帮助(包括你这个“白痴”,你应该这样做)都将不胜感激

public sealed class MyImage : Control {
    public MyImage() {
        this.DefaultStyleKey = typeof(MyImage);
        Loaded += MyImage_Loaded;
    }
    private async void MyImage_Loaded(object sender, RoutedEventArgs e) {
        ((Image)this.GetTemplateChild("currentImage")).Source = await ColorImage();
    }
    private async Task<WriteableBitmap> ColorImage() {
        // Get the image as a byte array
        StorageFile fileImage = await StorageFile.GetFileFromApplicationUriAsync(new Uri(BaseImageUri, UriKind.Absolute));
        ImageProperties propsImage = await fileImage.Properties.GetImagePropertiesAsync();
        int height = (int)propsImage.Height;
        int width = (int)propsImage.Width;
        byte[] baseImagePixels = await ReadPixels(fileImage);

        // Modify the mask by adding the accent color
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                byte B = baseImagePixels[4 * (y * height + x) + 0];
                byte G = baseImagePixels[4 * (y * height + x) + 1];
                byte R = baseImagePixels[4 * (y * height + x) + 2];
                byte A = baseImagePixels[4 * (y * height + x) + 3];
                if (R == 0x00 && G == 0x00 && B == 0x00 && A != 0xFF) {
                    baseImagePixels[4 * (y * height + x) + 0] = ColorBrush.Color.B;
                    baseImagePixels[4 * (y * height + x) + 1] = ColorBrush.Color.G;
                    baseImagePixels[4 * (y * height + x) + 2] = ColorBrush.Color.R;
                }
            }
        }
        WriteableBitmap coloredImage = new WriteableBitmap((int)propsImage.Width, (int)propsImage.Height);
        using (Stream stream = coloredImage.PixelBuffer.AsStream()) {
            await stream.WriteAsync(baseImagePixels, 0, baseImagePixels.Length);
        }
        return coloredImage;
    }
    private async Task<byte[]> ReadPixels(StorageFile file) {
        BitmapDecoder decoder = await BitmapDecoder.CreateAsync(await file.OpenAsync(FileAccessMode.Read));
        BitmapTransform transform = new BitmapTransform();
        PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Ignore,
            new BitmapTransform(),
            ExifOrientationMode.IgnoreExifOrientation,
            ColorManagementMode.DoNotColorManage);
        return pixelData.DetachPixelData();
    }
    public String BaseImageUri {
        get { return (String)GetValue(BaseImageUriProperty); }
        set {
            if (value.StartsWith("ms-appx:///")) {
                SetValue(BaseImageUriProperty, value);
            } else {
                SetValue(BaseImageUriProperty, "ms-appx:///" + value);
            }
        }
    }
    public static readonly DependencyProperty BaseImageUriProperty =
        DependencyProperty.Register("BaseImageUri", typeof(String), typeof(MyImage), new PropertyMetadata(0));
    public SolidColorBrush ColorBrush {
        get { return (SolidColorBrush)GetValue(ColorBrushProperty); }
        set { SetValue(ColorBrushProperty, value); }
    }
    public static readonly DependencyProperty ColorBrushProperty =
        DependencyProperty.Register("ColorBrush", typeof(SolidColorBrush), typeof(MyImage), new PropertyMetadata(0));
}
公共密封类MyImage:控件{
公共MyImage(){
this.DefaultStyleKey=typeof(MyImage);
已加载+=已加载的MyImage\u;
}
已加载私有异步void MyImage_(对象发送方,RoutedEventArgs e){
((Image)this.GetTemplateChild(“currentImage”)).Source=await ColorImage();
}
专用异步任务ColorImage(){
//以字节数组的形式获取图像
StorageFile fileImage=等待StorageFile.GetFileFromApplicationUrisync(新Uri(BaseImageUri,UriKind.Absolute));
ImageProperties propsImage=await fileImage.Properties.GetImagePropertiesAsync();
int height=(int)propsImage.height;
int width=(int)propsImage.width;
字节[]baseImagePixels=等待读取像素(fileImage);
//通过添加强调色修改遮罩
对于(int y=0;y
我找到了一个解决办法。我不知道为什么它会起作用。。。如果有人知道原因,我会很乐意接受这方面的教育。我为for循环添加了第二个更改

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pixelIndex = 4 * (y * width + x);
                byte B = baseImagePixels[pixelIndex];
                byte G = baseImagePixels[pixelIndex + 1];
                byte R = baseImagePixels[pixelIndex + 2];
                byte A = baseImagePixels[pixelIndex + 3];
                if (!(B == 0xFF && G == 0xFF && R == 0xFF && A == 0x00)) {
                    baseImagePixels[pixelIndex] = colorBrush.Color.B;
                    baseImagePixels[pixelIndex + 1] = colorBrush.Color.G;
                    baseImagePixels[pixelIndex + 2] = colorBrush.Color.R;
                    baseImagePixels[pixelIndex + 3] = colorBrush.Color.A;
                } else if (B == 0xFF && G == 0xFF && R == 0xFF && A == 0x00) {
                    baseImagePixels[pixelIndex] = 0x00;
                    baseImagePixels[pixelIndex + 1] = 0x00;
                    baseImagePixels[pixelIndex + 2] = 0x00;
                    baseImagePixels[pixelIndex + 3] = 0x00;
                }
            }
        }
for(int y=0;y
这对我来说似乎是个问题,但这只是一个猜测

某些图形库要求alpha<1.0的像素将其RGB组件存储为:

R' := R x A
G' := G x A
B' := B x A
A' := A
因此RGB→ <字母为零的代码>0xFFFFFF
无效

当RGB值超过其alpha值时,预期使用预乘alpha像素的混合算法会产生意外的结果

因此,在预乘alpha的情况下,完全透明的像素始终以0 alpha编码为
0x000000