对于使用PHP替换另一个图像的特定RGB颜色感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解使用php替换另一个图像的特定rgb颜色,并且为您提供关于android–如何在从一个图像移动到另
对于使用PHP替换另一个图像的特定RGB颜色感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解使用php替换另一个图像的特定rgb颜色,并且为您提供关于android – 如何在从一个图像移动到另一个图像的同时添加一条线作为手势?、c# – 使用OpenCV检测来自一个图像的对象是否在另一个图像中、c# – 使用混合模式颜色在另一个图像上绘制图像、Go: 用新的Map替换另一个Map线程安全吗?的宝贵知识。
本文目录一览:- 使用PHP替换另一个图像的特定RGB颜色(使用php替换另一个图像的特定rgb颜色)
- android – 如何在从一个图像移动到另一个图像的同时添加一条线作为手势?
- c# – 使用OpenCV检测来自一个图像的对象是否在另一个图像中
- c# – 使用混合模式颜色在另一个图像上绘制图像
- Go: 用新的Map替换另一个Map线程安全吗?
使用PHP替换另一个图像的特定RGB颜色(使用php替换另一个图像的特定rgb颜色)
这是原始图像.
一旦我用脚本处理这张照片.我有这个
脚本完美地替换了新的目标颜色.现在我想从蓝色变成背景.所以最后的想法是.这个女孩在背景图像我选择.
这是代码:
<?PHP //https://stackoverflow.com/a/32710756/1620626 function RGBtoHSL( $r,$g,$b ) { $r /= 255; $g /= 255; $b /= 255; $max = max( $r,$b ); $min = min( $r,$b ); $l = ( $max + $min ) / 2; $d = $max - $min; if( $d == 0 ){ $h = $s = 0; } else { $s = $d / ( 1 - abs( 2 * $l - 1 ) ); switch( $max ){ case $r: $h = 60 * fmod( ( ( $g - $b ) / $d ),6 ); if ($b > $g) { $h += 360; } break; case $g: $h = 60 * ( ( $b - $r ) / $d + 2 ); break; case $b: $h = 60 * ( ( $r - $g ) / $d + 4 ); break; } } return array( round( $h,2 ),round( $s,round( $l,2 ) ); } function HSLtoRGB( $h,$s,$l ){ $c = ( 1 - abs( 2 * $l - 1 ) ) * $s; $x = $c * ( 1 - abs( fmod( ( $h / 60 ),2 ) - 1 ) ); $m = $l - ( $c / 2 ); if ( $h < 60 ) { $r = $c; $g = $x; $b = 0; } else if ( $h < 120 ) { $r = $x; $g = $c; $b = 0; } else if ( $h < 180 ) { $r = 0; $g = $c; $b = $x; } else if ( $h < 240 ) { $r = 0; $g = $x; $b = $c; } else if ( $h < 300 ) { $r = $x; $g = 0; $b = $c; } else { $r = $c; $g = 0; $b = $x; } $r = ( $r + $m ) * 255; $g = ( $g + $m ) * 255; $b = ( $b + $m ) * 255; return array( floor( $r ),floor( $g ),floor( $b ) ); } /* ---------------CHANGE THESE------------------- */ $colorToReplace = RGBtoHSL(0,255,1);//target color $hueAbsoluteError = 7;//the more the clearer $replacementColor = RGBtoHSL(0,192,239);//new color /* ---------------------------------------------- */ $filename = 'images/01.png'; $im = imagecreatefrompng($filename); $out = imagecreatetruecolor(imagesx($im),imagesy($im)); $transColor = imagecolorallocatealpha($out,254,127); imagefill($out,$transColor); for ($x = 0; $x < imagesx($im); $x++) { for ($y = 0; $y < imagesy($im); $y++) { $pixel = imagecolorat($im,$x,$y); $red = ($pixel >> 16) & 0xFF; $green = ($pixel >> 8) & 0xFF; $blue = $pixel & 0xFF; $alpha = ($pixel & 0x7F000000) >> 24; $colorHSL = RGBtoHSL($red,$green,$blue); if ((($colorHSL[0] >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){ $color = HSLtoRGB($replacementColor[0],$replacementColor[1],$colorHSL[2]); $red = $color[0]; $green= $color[1]; $blue = $color[2]; } if ($alpha == 127) { imagesetpixel($out,$y,$transColor); } else { imagesetpixel($out,imagecolorallocatealpha($out,$red,$blue,$alpha)); } } } imagecolortransparent($out,$transColor); imagesavealpha($out,TRUE); header('Content-type: image/png'); imagepng($out); ?>
以下是您上面代码的最后一部分,显示了这个想法:
$filename = 'images/01.png'; $bgFilename = 'images/background.png'; $im = imagecreatefrompng($filename); $bg = imagecreatefrompng($bgFilename); $out = imagecreatetruecolor(imagesx($im),$y); $bgPixel = imagecolorat($bg,$y); $red = ($pixel >> 16) & 0xFF; $green = ($pixel >> 8) & 0xFF; $blue = $pixel & 0xFF; $alpha = ($pixel & 0x7F000000) >> 24; $colorHSL = RGBtoHSL($red,$blue); if ((($colorHSL[0] >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){ // Instead of taking the replacementColor /* $color = HSLtoRGB($replacementColor[0],$colorHSL[2]); */ /* $red = $color[0]; */ /* $green= $color[1]; */ /* $blue = $color[2]; */ // We just take colors from the backround image pixel $red = ($bgPixel >> 16) & 0xFF; $green = ($bgPixel >> 8) & 0xFF; $blue = $bgPixel & 0xFF; } if ($alpha == 127) { imagesetpixel($out,TRUE); header('Content-type: image/png'); imagepng($out);
结果可能如下所示:
android – 如何在从一个图像移动到另一个图像的同时添加一条线作为手势?
我正在为Android手机制作自己的Pattern Lock,我已完成编码,因为当我点击图像时它会在数组中存储一个整数,当用户重新输入相同的密码时,它会匹配两个数组并相应地打开锁定,我的代码工作正常但是现在我必须以一条线的形式添加手势,同时从一个图像到另一个图像(如图案锁定)我也想在触摸图像而不是单击时将整数存储在数组中它…
指导我如何执行此操作是我的图像点击事件的示例代码
public void Image1(View view) {
// Toast.makeText(this, "You clicked Image 1!",
// Toast.LENGTH_SHORT).show();
myArray[0] = 1;
// builder.append("" + myArray[0] + " ");
// Toast.makeText(this, myArray, Toast.LENGTH_LONG).show();
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image2(View view) {
// Toast.makeText(this, "You clicked Image 2!",
// Toast.LENGTH_SHORT).show();
myArray[1] = 2;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image3(View view) {
// Toast.makeText(this, "You clicked Image 3!",
// Toast.LENGTH_SHORT).show();
myArray[2] = 3;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image4(View view) {
// Toast.makeText(this, "You clicked Image 4!",
// Toast.LENGTH_SHORT).show();
myArray[3] = 4;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image5(View view) {
// Toast.makeText(this, "You clicked Image 5!",
// Toast.LENGTH_SHORT).show();
myArray[4] = 5;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image6(View view) {
// Toast.makeText(this, "You clicked Image 6!",
// Toast.LENGTH_SHORT).show();
myArray[5] = 6;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image7(View view) {
// Toast.makeText(this, "You clicked Image 7!",
// Toast.LENGTH_SHORT).show();
myArray[6] = 7;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image8(View view) {
// Toast.makeText(this, "You clicked Image 8!",
// Toast.LENGTH_SHORT).show();
myArray[7] = 8;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
public void Image9(View view) {
// Toast.makeText(this, "You clicked Image 9!",
// Toast.LENGTH_SHORT).show();
myArray[8] = 9;
ImageView kk = (ImageView) view;
Drawable d = getResources().getDrawable(R.drawable.unlock);
kk.setimageDrawable(d);
}
解决方法:
使用ACTION_DOWN,ACTION_MOVE,ACTION_UP实现onTouchEvent(MotionEvent ev).当您的手指移动时,从先前的坐标到当前坐标绘制一条线.
使用ev.getX()ev.getY()获取坐标
我刚才想到了两个解决方案:
>当检测到触摸事件时,在ACTION_DOWN处,在父视图的顶部绘制透明的VIEW,只要ACTION_MOVE正在处理中,使其成为Canvas并绘制.
>使用SurfaceView而不是常规View. SurfaceView上的一个示例绘制:http://www.droidnova.com/playing-with-graphics-in-android-part-ii,160.html
c# – 使用OpenCV检测来自一个图像的对象是否在另一个图像中
http://imgur.com/luj2Z
然后,我有一个大的候选图像集,我需要确定哪一个最有可能包含该对象,例如:
http://imgur.com/yBWgc
所以我需要为每个图像生成一个分数,其中最高分对应于最可能包含目标对象的图像.现在,在这种情况下,我有以下条件/约束来处理/周围:
1)我可以在不同的角度获得多个样本图像.
2)样本图像可能与候选图像处于不同的分辨率,角度和距离.
3)有很多候选图像(> 10,000),因此它必须相当快.
4)我愿意为速度牺牲一些精度,所以如果它意味着我们必须搜索前100名而不是前10名,这很好,可以手动完成.
5)我可以手动操作样本图像,例如概述我想要检测的对象;候选图像不能手动操作,因为太多了.
6)我根本没有OpenCV或计算机视觉的真实背景,所以我从头开始.
我最初的想法是首先在样本图像中围绕对象绘制粗略轮廓.然后,我可以识别候选图像中的对象和角落的角落.我可以分析每个角落周围的像素,看它们是否看起来相似,然后按每个角落的最大相似度得分的总和进行排名.我也不确定如何量化类似的像素.我想只是他们的RGB值的欧几里德距离?
问题在于它忽略了对象的中心.在上面的例子中,如果耳环的角落都在金框附近,那么它就不会考虑耳环内的红色,绿色和蓝色宝石.我想我可以通过查看所有角点并通过沿着它们之间的线采样某些点来确定相似性来改善这一点.
所以我有几个问题:
A)这种思路一般是否有意义或是否有我遗漏的东西?
B)我应该调查OpenCV的哪些特定算法?我知道有多个角点检测算法,但我只需要一个,如果差异都在边缘上进行优化,那么我最好用.
C)使用算法的任何示例代码有助于我的理解?
我的语言选择是Python或C#.
解决方法
当然,这是一个非常高级别的解释.魔鬼在细节中,对于那些你应该阅读一些文章.从David Lowe开始Distinctive image features from scale-invariant keypoints,然后阅读有关SURF的论文.
另外,请考虑将此问题移至Signal and Image Processing Stack Exchange
c# – 使用混合模式颜色在另一个图像上绘制图像
如果图像顶部只有一个渐变,结果可能如下所示:
我在某处找到的颜色混合模式的描述是:
颜色将下层的色调和饱和度改变为上层的色调和饱和度,但仅留下亮度.
到目前为止我的代码是:
using(var g = Graphics.FromImage(canvas)) { // draw the lower image g.DrawImage(lowerImg,left,top); // creating a gradient and draw on top using (Brush brush = new LinearGradientBrush(new Rectangle(0,canvasWidth,canvasHeight),Color.Violet,Color.Red,20)) { g.FillRectangle(brush,canvasHeight); } }
但那是 – 当然 – 只是在较低的图像上绘画.
所以问题是:
如何使用Photoshop中提供的混合模式“颜色”在另一个图像上绘制图像?
编辑:
为了使我更清楚我想要实现的目标:
如果有人想使用图像进行测试:
解决方法
using (Bitmap lower = new Bitmap("lower.png")) using (Bitmap upper = new Bitmap("upper.png")) using (Bitmap output = new Bitmap(lower.Width,lower.Height)) { int width = lower.Width; int height = lower.Height; var rect = new Rectangle(0,width,height); BitmapData lowerData = lower.LockBits(rect,ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); BitmapData upperData = upper.LockBits(rect,PixelFormat.Format24bppRgb); BitmapData outputData = output.LockBits(rect,ImageLockMode.writeonly,PixelFormat.Format24bppRgb); unsafe { byte* lowerPointer = (byte*) lowerData.Scan0; byte* upperPointer = (byte*) upperData.Scan0; byte* outputPointer = (byte*) outputData.Scan0; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { HSLColor lowerColor = new HSLColor(lowerPointer[2],lowerPointer[1],lowerPointer[0]); HSLColor upperColor = new HSLColor(upperPointer[2],upperPointer[1],upperPointer[0]); upperColor.Luminosity = lowerColor.Luminosity; Color outputColor = (Color) upperColor; outputPointer[0] = outputColor.B; outputPointer[1] = outputColor.G; outputPointer[2] = outputColor.R; // Moving the pointers by 3 bytes per pixel lowerPointer += 3; upperPointer += 3; outputPointer += 3; } // Moving the pointers to the next pixel row lowerPointer += lowerData.Stride - (width * 3); upperPointer += upperData.Stride - (width * 3); outputPointer += outputData.Stride - (width * 3); } } lower.UnlockBits(lowerData); upper.UnlockBits(upperData); output.UnlockBits(outputData); // Drawing the output image }
Go: 用新的Map替换另一个Map线程安全吗?
这是一个Stackoverflow上的问题但其实我去年就问过这个问题,但是被社区删除了,因为他们觉得引发了数据竞态报告就理应加锁,不需要讨论。但是在一些场景中,性能影响是需要考虑的,实际工作中也不可避免地用到各种奇淫技巧,所以这是值得讨论的。现在我找到了答案。
场景
这个问题其是只适用于少数情况,比如对于一个一写多读的Map,你可以理解为它是“只读”的Map。如果对其进行替换,不管是用锁还是不用锁,期望的行为就是替换前是旧Map,替换后是新Map,替换的瞬间,新旧Map同时存在,这是不可避免也是理所当然的。所以唯一需要讨论的就是,不使用锁是否会产生恐慌或是读取到不存在的错误数据?
太长不看:
从底层角度看,在绝大多数处理器架构上以及已知的Go版本中,对于map
的覆盖写入是线程安全的。这很像C/C++中的实现定义行为(IB,Implementation-defined Behaviour)。但GO官方并不鼓励这种行为,他们觉得,对于数据竞态,应该采用宏观的串行措施保证程序安全,所以对任何宏观上并发读写的变量都会产生数据竞态警告。
详细:
首先,很多人觉得map
是hmap
结构体,但是严格来说并不是这样,更准确来说map
只是一个指向hmap
的指针。因此,map
的大小不会超过一个机器字长,unsafe.Sizeof(map1)
在32位系统上显示4字节,在64位系统上显示8字节。
其次,你提到了机器字长,所以你应该知道,对于不超过机器字长的类型赋值,在绝大多数CPU中,是可以只通过一条指令完成的。那对map
进行覆盖赋值用了多少条指令呢?
我们写一个这样的程序,左边是行号。为了更加严谨,我们对m1
赋值两次,原因后面会说。
1 package main
2
3 func main() {
4 m1 := make(map[int]int, 20)
5 m2 := make(map[int]int, 20)
6 m1 = m2
7 m1 = m2
8 _ = m1
9 }
将代码生成Go汇编。
go build -gcflags="-S -N -l" main.go 1> goasm.txt 2>&1
我们可以看到,Go汇编代码显示第6行只用到了一条Go汇编语句。但是第7行用了两条,但是我们发现都只是读写寄存器而已,将数据从内存读到寄存器,从寄存器写入内存,这个过程不存在中间态,因为一个核心的寄存器不存在被其他核心覆盖的可能。所以核心操作只有一条,就是将寄存器赋值给内存MOV REG MEM
。
0x0070 00112 (main.go:6) MOVQ AX, main.m1+32(SP)
0x0075 00117 (main.go:7) MOVQ main.m2+24(SP), DX
0x007a 00122 (main.go:7) MOVQ DX, main.m1+32(SP)
由于Go汇编语句只是伪汇编,为的是在不同硬件平台上都能编译。所以我我们直接反汇编。
objdump -S -d main > objdump.txt
在amd64 linux机器上,反汇编的结果如下。核心操作是将寄存器的值写入内存。
m1 = m2
4576f0: 48 89 44 24 20 mov %rax,0x20(%rsp)
m1 = m2
4576f5: 48 8b 54 24 18 mov 0x18(%rsp),%rdx
4576fa: 48 89 54 24 20 mov %rdx,0x20(%rsp)
所以,问题2,MOV
操作是原子的吗?
是的,在现今绝大多数的架构上,对于内存对齐的不长于机器字长的MOV
操作,都是原子的。
参考Go的内存模型,Go内存对齐策略,英特尔64架构开发手册。
Otherwise, a read r of a memory location x that is not larger than a machine word must observe some write w such that r does not happen before w and there is no write w'' such that w happens before w'' and w'' happens before r. That is, each read must observe a value written by a preceding or concurrent write.
这段话很晦涩,但总的意思是每一次不超过字长的读写都是完整的、原子的,不存在读/写了一半的情况。
The following minimal alignment properties are guaranteed:
1. For a variable x of any type: unsafe.Alignof(x) is at least 1. 2. For a variable x of struct type: unsafe.Alignof(x) is the largest of all the values unsafe.Alignof(x.f) for each field f of x, but at least 1. 3. For a variable x of array type: unsafe.Alignof(x) is the same as the alignment of a variable of the array''s element type.
A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.
Go保证变量在内存以某种方式对齐。
8.1.1 Guaranteed Atomic Operations
The Intel486 processor (and newer processors since) guarantees that the following basic memory operations will
always be carried out atomically:
• Reading or writing a byte
• Reading or writing a word aligned on a 16-bit boundary
• Reading or writing a doubleword aligned on a 32-bit boundary
The Pentium processor (and newer processors since) guarantees that the following additional memory operations
will always be carried out atomically:
• Reading or writing a quadword aligned on a 64-bit boundary
• 16-bit accesses to uncached memory locations that fit within a 32-bit data bus
The P6 family processors (and newer processors since) guarantee that the following additional memory operation
will always be carried out atomically:
• Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line
英特尔开发手册保证对于目前绝大多数英特尔处理器,对不超过64位的寄存器读写操作保证原子。
所以答案是,可以,在绝大多数处理器架构上以及已知的Go版本中,对于map
的覆盖写入是线程安全的。尽管Go官方并不鼓励这种做法,并警告到
编写无数据竞争的Go程序的程序员,可以依赖这些程序的串行执行,就像其他现代编程语言一样。
对于包含数据竞争的程序来说,无论是程序员还是编译器,都应该记住一个建议:不要过于聪明。
- [1]The Go Memory Model
- [2]Size and alignment guarantees
- [3]Intel® 64 and IA-32 Architectures Developer''s Manual: Vol. 3A
我们今天的关于使用PHP替换另一个图像的特定RGB颜色和使用php替换另一个图像的特定rgb颜色的分享已经告一段落,感谢您的关注,如果您想了解更多关于android – 如何在从一个图像移动到另一个图像的同时添加一条线作为手势?、c# – 使用OpenCV检测来自一个图像的对象是否在另一个图像中、c# – 使用混合模式颜色在另一个图像上绘制图像、Go: 用新的Map替换另一个Map线程安全吗?的相关信息,请在本站查询。
本文标签: