问题描述
今天做了个测试,研究了下图形的构成,图形由ARGB构成,每个单元有255个组成,就是255*255*255*255接近40亿个颜色,会一点SIVERLIGHT也知道如何绘制方块和填充颜色,当然用其他技术也行,就想通过程序写一个40亿颜色的程序,看看这40亿的颜色到底是什么鬼。这里遇到了很多问题,主要是算法,当然还有个重要的问题是内存管理,用4个255进行循环,40亿的计算量,我的计算机(I7,8G,650M)光是打印这40亿的数字估计可能需要几个小时,我精简了算法,做了600多W颜色的填充,都已经经常超出内存,每次到100多W的时候,就报超出系统内存。短时间可能暂时无法完成该程序,但这是我的一个目标,在我有生之年,不管用什么技术,花多少时间,我将亲自用程序绘制出40多亿的颜色,今天写这个也是给自己订个目标,希望有缘的人,能看到,共同来实现这个目标,非常感谢。贴上,现在研究的代码publicMainPage(){InitializeComponent();SizeChanged+=(o,e)=>{intdw=25;doubleAllBorder=Math.Pow(dw,4);doublebordersize=ActualWidth/(Convert.ToDouble(AllBorder)/ActualHeight);List<Grid>allPanels=newList<Grid>();List<Grid>allgrids=newList<Grid>();Int64MaxBorder=Convert.ToInt64(Convert.ToDouble((AllBorder/ActualHeight).ToString("0.00")));for(inti=0;i<ActualHeight;i++){Gridp=newGrid();p.Height=bordersize;RowDefinitionrd=newRowDefinition();rd.Height=newGridLength(1);LayoutRoot.RowDefinitions.Add(rd);allPanels.Add(p);LayoutRoot.Children.Add(p);for(intj=0;j<MaxBorder;j++){ColumnDefinitioncd=newColumnDefinition();cd.Width=newGridLength(1,GridUnitType.Star);p.ColumnDefinitions.Add(cd);Gridg=newGrid();if(j%2==0)g.Background=newSolidColorBrush(Colors.White);else{g.Background=newSolidColorBrush(Colors.Red);}p.Children.Add(g);Grid.SetColumn(g,j);allgrids.Add(g);}Grid.SetRow(p,i);}return;Int32nowxh=0;Int32nowhh=0;try{for(bytea=0;a<dw;a++){for(byter=0;r<dw;r++){for(byteg=0;g<dw;g++){for(byteb=0;b<dw;b++){if(nowxh%10==0){allgrids[nowxh].Background=newSolidColorBrush(Color.FromArgb(a,r,g,b));nowxh=nowxh+1;}}}}}}catch(Exceptionex){throwex;}MessageBox.Show("1");};}代码比较简单,算法也比较简单,估计还是对内存管理和分配涉入太浅,希望通过这个程序,对内存管理,分配,释放能有个充分的认识,欢迎大家讨论更贴。
解决方案
解决方案二:
我是小白,说错了勿怪,可以分成255次来吗,这样一次用的内存就小了吧。
解决方案三:
首先Alpha透明通道并不是颜色,现在也应该还没有显示器能把Alpha真正透明显示,然后每个通道0-255是256种。需要考虑的只是RGB的24位16777216种颜色。想看结果这里有:,全部都是使用了所有16777216颜色的图。实际上一张4096*4096的图就能放下了。你那样用控件显示显然开销会非常大,就失去了意义,改成绘制一个图片才比较现实。也就是创建个Bitmap,LockBits后把0-16777215对应的24位二进制填进去。然而这只不过是人为定义的一种色彩空间,还有其它的色彩空间,呈现出来的结果也会因为操作系统设置、显卡设置、显示器不同而不同。颜色不是离散的,有无穷多种。甚至使用RGB三色来模拟其它颜色也只是对人视觉系统的一种欺骗,而就算眼睛接收到的光相同,人脑在处理的时候也会有偏差,之前的白金/蓝黑就是很好的例子。这个事情作为提高技术的短期目标还行,并不是件“有生之年”的事。让显示/打印/投影设备能完美的重现自然界的所有颜色才是。
解决方案四:
这个倒是没想过,感觉研究这个,对现在的已有基础似乎没啥助力
解决方案五:
完全听不懂,汗一个!
解决方案六:
看你直接new感觉不太对啊,这样内存是不够用。考虑享元模式
解决方案七:
算法不复杂,关键是显示器不够大
解决方案八:
不要用控件,直接绘图,并且调用LockBits
解决方案九:
40亿你能看得完?、、、还特么不如直接打开ps调色板慢慢看个够
解决方案十:
这个不就是色环、调色板吗?有什么区别。
解决方案十一:
我觉得就算计算机的分辨率有这么高,我们的眼睛分辨率也跟不上啊,根本看不出来的
解决方案十二:
引用楼主flag5418的回复:
...我将亲自用程序绘制出40多亿的颜色...
一个颜色占4个字节,单单存放40多亿的颜色就要16G,还没算上40亿个Grid的内存占用。因此,一次性把所有的方块画出来是不实际的。要绘制40多亿的颜色还是可以的(这里不讨论显卡/显示器的颜色响应),条件就是每次只显示部分颜色。下例用了40个方块,但通过滚动条来显示40多亿的颜色(Grid加了背景图案,以便观察方块的透明度)。<Grid><Grid.Background><VisualBrushTileMode="Tile"Viewport="0,0,20,20"ViewportUnits="Absolute"Viewbox="0,0,20,20"ViewboxUnits="Absolute"><VisualBrush.Visual><Grid><PathData="M020L200"Stroke="Gray"/><PathData="M00L2020"Stroke="Gray"/></Grid></VisualBrush.Visual></VisualBrush></Grid.Background><Grid.ColumnDefinitions><ColumnDefinitionWidth="*"/><ColumnDefinitionWidth="auto"/></Grid.ColumnDefinitions><CanvasName="canvas"/><ScrollBarGrid.Column="1"Maximum="100000000"Scroll="scrollbar_Scroll"/></Grid>
publicpartialclassMainWindow:Window{publicMainWindow(){InitializeComponent();for(inti=0;i<BlocksPerLine*LinesPerPage;i++){Borderborder=newBorder(){Width=RectSize,Height=RectSize,BorderThickness=newThickness(1),BorderBrush=Brushes.Black};Canvas.SetLeft(border,(i%BlocksPerLine)*(double)BlockSize);Canvas.SetTop(border,(i/BlocksPerLine)*(double)BlockSize);border.Child=newTextBlock();this.canvas.Children.Add(border);}Layout(0);}privatevoidLayout(doublepercentage){uintoffset=(uint)(percentage*uint.MaxValue)/BlocksPerLine*BlocksPerLine;for(inti=0;i<this.canvas.Children.Count;i++){byte[]bs=BitConverter.GetBytes((uint)(offset+i));Colorcolor=Color.FromArgb(bs[3],bs[2],bs[1],bs[0]);Borderborder=this.canvas.Children[i]asBorder;border.Background=newSolidColorBrush(color);(border.ChildasTextBlock).Text=color.ToString();}}privatevoidscrollbar_Scroll(objectsender,System.Windows.Controls.Primitives.ScrollEventArgse){Layout(e.NewValue/(senderasSystem.Windows.Controls.Primitives.ScrollBar).Maximum);}constintRectSize=100,BlockSize=120,BlocksPerLine=4,LinesPerPage=10;}