photo.php,EasyPhoto.php

2023-10-29

class EasyPhoto{

//所有图层

private $layers=array();

//当前活动图层

private $ActiveLayer;

//对象实例,单实例模式

private static $instance;

private $imageLayers=array();

public function __construct($fileName=null,$options=array()) {

if(!extension_loaded('gd')){

throw new Exception('需要gd库支持!');

}

if(is_file($fileName)){

$this->addLayer($fileName);

}

}

/*

增加一个图像图层

@param mixed $image 加入图片的完整路径

@param int $x 图层的x坐标

@param int $y图层的y坐标

@param string $pos图层的相对位置,默认是LT

C for center L for left R for right B for bottom T for top

可选值:LT|LC|LB|CT|CC|CB|RT|RC|RB

@param int $opacity图层的透明度

*/

public function addLayer($image,$options=array()){

if(is_string($image)){

$imageName=$image;

$this->imageLayers[]=$imageName;

$image=self::createFromImage($image);

}

$defaults=array(

'x'=>0,

'y'=>0,

'pos'=>'LT',

'opacity'=>100

);

$config=array_merge($defaults,$options);

$this->ActiveLayer=array(

'layer'=>$image,

'width'=>imagesx($image),

'height'=>imagesy($image),

'x'=>$config['x'],

'y'=>$config['y'],

'pos'=>$config['pos'],

'opacity'=>$config['opacity']

);

if(isset($imageName)){

$this->ActiveLayer['name']=$imageName;

}

$this->layers[]=$this->ActiveLayer;

return $this;

}

/*

取得所有图层中最大的宽和高

*/

private function getLayersMaxSize(){

$width=array();

$height=array();

foreach ($this->layers as $layer){

$width[]=$layer['width'];

$height[]=$layer['height'];

}

return array('width'=>max($width),'height'=>max($height));

}

/*

合并所有的图层,图层信息会覆盖成合并后的图层信息

*/

public function mergeLayers(){

$dst_layer=array();

$maxSize=$this->getLayersMaxSize();

foreach ($this->layers as $layer){

if(empty($dst_layer)){

$dst_layer=array(

'width'=>$maxSize['width'],

'height'=>$maxSize['height'],

'x'=>0,

'y'=>0,

'pos'=>'LT',

'opacity'=>100

);

$dst_layer['layer']=self::createTransparentBg($maxSize['width'],$maxSize['height']);

}

$realPosition=self::getRealPosition($maxSize['width'],$maxSize['height'],$layer);

imagecopymerge($dst_layer['layer'], $layer['layer'], $realPosition['x'], $realPosition['y'], 0, 0, $layer['width'], $layer['height'], $layer['opacity']);

}

$this->ActiveLayer=$dst_layer;

$this->layers=array($dst_layer);

return $this;

}

public function setLayerProperty($property=array()){

$index=array_search($this->ActiveLayer, $this->layers);

$this->ActiveLayer=array_merge($this->ActiveLayer,$property);

$this->layers[$index]=$this->ActiveLayer;

return $this;

}

/*

调整图像大小,假如存在多个图层的话,会先合并成一个图层再调整大小

@param int $width 设置的宽度,当为auto时候,直接使用mode 5

@param int $height 设置的高度,当为auto时候,直接使用mode 5

@param array $options 可选参数

@param int $options['mode']调整图片大小的5种模式, default 2

1:直接根据给定的宽高来缩放图形,如果给定的比例不一致会导致图片变形

2:根据给定的宽高,按照原图片的比例全部显示,比例跟原来不一致会差生空白

3:按照图片比例,图像以最大的边显示,多余的部分会去掉,造成生成的缩略图尺寸,其中宽或高会小于指定的

4:图片截取模式,比例不一致时,原图会按原来比例截取,截取中心点可以设定,默认是图片中心点CC

5:给定宽或高按照图片原来比例来调整图片大小

@param string $options['pos'] 截图中心,只在mode 4生效

C for center L for left R for right B for bottom T for top

可选值:LT|LC|LB|CT|CC|CB|RT|RC|RB

*/

public function resize($width,$height,$options=array()){

$default=array(

'mode'=>2,

'pos'=>'CC'

);

$config=array_merge($default,$options=array());

if(count($this->layers)>1){

$this->mergeLayers();

}

if($width=='auto'||$height=='auto'){

$config['mode']=5;

}

switch($config['mode']){

//直接根据给定的宽高来缩放图形,如果给定的比例不一致会导致图片变形

case 1:

$tmpImage=self::createTransparentBg($width, $height);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $width, $height, $this->ActiveLayer['width'], $this->ActiveLayer['height']);

break;

//根据给定的宽高,按照原图片的比例全部显示,比例跟原来不一致会差生空白

case 2:

$tmpImage=self::createTransparentBg($width, $height);

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

$dstX=0;

$dstY=round(($height-$resizeH)*1.0/2);

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

$dstY=0;

$dstX=round(($width-$resizeW)*1.0/2);

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

//按照图片比例,图像以最大的边显示,多余的部分会去掉,造成生成的缩略图尺寸,其中宽或高会小于指定的

case 3:

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

}else{

$resizeW=$width;

$resizeH=$height;

}

$tmpImage=self::createTransparentBg($resizeW, $resizeH);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

//图片截取模式,比例不一致时,原图会按原来比例截取,截取中心点可以设定,默认是图片中心点CC

case 4:

$tmpImage=self::createTransparentBg($width, $height);

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeW=round($imageWidth*$height*1.0/$imageHeight);

$resizeH=$height;

$dstX=round(($resizeW-$width)*1.0/2);

$dstX=-$dstX;

$dstY=0;

}else if($imgRate

$resizeW=$width;

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$dstX=0;

$dstY=round(($resizeH-$height)*1.0/2);

$dstY=-$dstY;

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

switch ($config['pos']){

case 'LT':

$dstX=0;

$dstY=0;

break;

case 'LC':

$dstX=0;

break;

case 'LB':

$dstX=0;

$dstY=$dstY*2;

break;

case 'TC':

$dstY=0;

break;

case 'CC':

break;

case 'CB':

$dstY=$dstY*2;

break;

case 'RT':

$dstY=0;

$dstX=$dstX*2;

break;

case 'RC':

$dstX=$dstX*2;

break;

case 'RB':

$dstY=$dstY*2;

$dstX=$dstX*2;

break;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY,0,0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

//给定宽或高按照图片原来比例来调整图片大小

case 5:

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

if($width=='auto'){

$resizeW=round($imageWidth*$height*1.0/$imageHeight);

$resizeH=$height;

}else if($height=='auto'){

$resizeW=$width;

$resizeH=round($imageHeight*$width*1.0/$imageWidth);

}

$tmpImage=self::createTransparentBg($resizeW, $resizeH);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0,0,0,0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

}

$this->ActiveLayer['layer']=$tmpImage;

return $this;

}

public function resizeByPresent($widthPCT,$heightPCT,$options=array()){

$default=array(

'pos'=>'CC',

'mode'=>2

);

$config=array_merge($default,$options);

if(count($this->layers)>1){

$this->mergeLayers();

}

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$width=$imageWidth*$widthPCT*1.0/100;

$height=$imageHeight*$heightPCT*1.0/100;

if($widthPCT==$heightPCT){

$options['mode']=1;

}

switch($options['mode']){

case 1:

$tmpImage=self::createTransparentBg($width, $height);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $width, $height, $imageWidth, $imageHeight);

break;

case 2:

$tmpImage=self::createTransparentBg($width, $height);

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

$dstX=0;

$dstY=round(($height-$resizeH)*1.0/2);

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

$dstY=0;

$dstX=round(($width-$resizeW)*1.0/2);

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

case 3:

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

}else{

$resizeW=$width;

$resizeH=$height;

}

$tmpImage=self::createTransparentBg($resizeW, $resizeH);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

case 4:

$tmpImage=self::createTransparentBg($width, $height);

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeW=round($imageWidth*$height*1.0/$imageHeight);

$resizeH=$height;

$dstX=round(($resizeW-$width)*1.0/2);

$dstX=-$dstX;

$dstY=0;

}else if($imgRate

$resizeW=$width;

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$dstX=0;

$dstY=round(($resizeH-$height)*1.0/2);

$dstY=-$dstY;

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

switch ($config['pos']){

case 'LT':

$dstX=0;

$dstY=0;

break;

case 'LC':

$dstX=0;

break;

case 'LB':

$dstX=0;

$dstY=$dstY*2;

break;

case 'TC':

$dstY=0;

break;

case 'CC':

break;

case 'CB':

$dstY=$dstY*2;

break;

case 'RT':

$dstY=0;

$dstX=$dstX*2;

break;

case 'RC':

$dstX=$dstX*2;

break;

case 'RB':

$dstY=$dstY*2;

$dstX=$dstX*2;

break;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY,0,0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

}

$this->ActiveLayer['layer']=$tmpImage;

return $this;

}

/*

图片剪裁

@param int $width剪裁后的宽度

@param int $height剪裁后的高度

@param array $options可选参数

@param int $options['x'] 相对于pos的x坐标

@param int $options['y'] 相对于pos的y坐标

@param string $options['pos'] 定位中心,以哪个点为参考中心

*/

public function crop($width,$height,$options=array()){

if(count($this->layers)>1){

$this->mergeLayers();

}

$defaults=array(

'x'=>0,

'y'=>0,

'pos'=>'LT'

);

$config=array_merge($defaults,$options);

$dst_image=self::createTransparentBg($width, $height);

$dst_layer=array(

'layer'=>$dst_image,

'width'=>$width,

'height'=>$height,

'x'=>$config['x'],

'y'=>$config['y'],

'pos'=>$config['pos']

);

$cropInfo=array('width'=>$width,'height'=>$height,'x'=>$config['x'],'y'=>$config['y'],'pos'=>$config['pos']);

$realPos=self::getCropPos($dst_layer, $this->ActiveLayer);

imagecopyresampled($dst_layer['layer'], $this->ActiveLayer['layer'], 0, 0, $realPos['x'], $realPos['y'], $width, $height, $width, $height);

$this->ActiveLayer=$dst_layer;

}

/*

保存图片,会自动获取扩展名来保存图片类型

@param string $fileName指定图片保存的完整路径(含路径跟文件名) 如:Uploads/photo/123.png

@param int $quality 指定jpg图片保存的质量,默认100

@param boolean $remove 是否删除使用的图片,默认删除

*/

public function save($fileName,$remove=true,$quality=100){

if(count($this->layers)>1){

$this->mergeLayers();

}

$fileInfo=pathinfo($fileName);

$extension=strtolower($fileInfo['extension']);

switch($extension){

case 'jpg':

imagejpeg($this->ActiveLayer['layer'],$fileName,$quality);

break;

case 'png':

imagepng($this->ActiveLayer['layer'],$fileName);

break;

case 'gif':

imagegif($this->ActiveLayer['layer'],$fileName);

break;

}

imagedestroy($this->ActiveLayer['layer']);

if($remove===true){

foreach ($this->imageLayers as $img){

unlink($img);

}

}

unset($this->ActiveLayer);

unset($this->layers);

unset($this->imageLayers);

$this->layers=array();

$this->imageLayers=array();

}

/*

设置当前图层的level,数值越大的图层越排在前面 (相当于zIndex),当level过大(大于图层数量)时,level值会设置成图层数量

@param int $level 图层的level

*/

public function setLevel($level){

$index=array_search($this->ActiveLayer, $this->layers);

unset($this->layers[$index]);

array_splice($this->layers, $level,0,array($this->ActiveLayer));

return $this;

}

public function topLayer(){

$len=count($this->layers);

$this->setLevel($len);

return $this;

}

/*

根据index值获取图层,并将当前图层替换成取得的图层

@param int $index 如果没设置过图层level的话,图层的index值按照添加的顺序从0-len-1

*/

public function getLayer($index){

$layersLen=count($this->layers);

$index=$index>0?$index:0;

$index=$index

$this->ActiveLayer=$this->layers[$index];

return $this;

}

/*

根据图片的名字获取图层,只支持通过图片创建的图层,并将当前图层替换成取得的图层

@param string $fileName 支持三种模式:1.图片完整的路径;2.图片名字;3.图片名字(不带扩展名)

*/

public function getLayerByFileName($fileName){

foreach ($this->layers as $layer){

if(empty($layer['name'])){

continue;

}

if($layer['name']===$fileName){

$this->ActiveLayer=$layer;

break;

}else{

$fileInfo=pathinfo($layer['name']);

if($fileName===$fileInfo['basename'] || $fileName === $fileInfo['filename']){

$this->ActiveLayer=$layer;

break;

}

}

}

return $this;

}

/*

将web颜色值转化成RGB值

@param string $hex web颜色值

*/

public static function convertHexToRGB($hex){

return array(

'R' => (int) base_convert(substr($hex, 0, 2), 16, 10),

'G' => (int) base_convert(substr($hex, 2, 2), 16, 10),

'B' => (int) base_convert(substr($hex, 4, 2), 16, 10),

);

}

/*

创建一个透明的背景

@param int $width

@param int $height

@param string $color web颜色值

@opacity int $opacity 0-127 127是透明,0是不透明

*/

public static function createTransparentBg($width, $height,$color ='ffffff',$opacity = 127){

$RGBColors = self::convertHexToRGB($color);

$image = imagecreatetruecolor($width, $height);

$color = imagecolorallocatealpha($image, $RGBColors['R'], $RGBColors['G'], $RGBColors['B'],$opacity);

imagecolortransparent($image,$color);

imagefill($image, 0, 0, $color);

return $image;

}

/*

根据图片创建gd image resource

@param string $fileName图像文件的完整路径

*/

public static function createFromImage($fileName){

if(file_exists($fileName)&&!is_dir($fileName)){

$imgInfo=getimagesize($fileName);

$width=$imgInfo[0];

$height=$imgInfo[1];

$type=$imgInfo[2];

if($type>3){

return array('status'=>1,'msg'=>'只支持jpg,png,gif这三种格式的图像文件');

}

switch ($type){

//gif

case 1:

$image=imagecreatefromgif($fileName);

break;

//jpg

case 2:

$image=imagecreatefromjpeg($fileName);

break;

//png

case 3:

$image=imagecreatefrompng($fileName);

break;

}

}else{

throw new Exception('不是一个有效的图像文件');

}

return $image;

}

/*

取得图像图层的绝对位置

@param string $dstW 目标图层的宽

@param string $dstH 目标图层的高

@param array $layer 需要获取绝对位置的图层

*/

public static function getRealPosition($dstW,$dstH,$layer){

$posOut=array();

switch ($layer['pos']){

case 'LT':

$posOut=array('x'=>$layer['x'],'y'=>$layer['y']);

break;

case 'LC':

$offsetH=round(($dstH-$layer['height'])*1.0/2);

$posOut=array('x'=>$layer['x'],'y'=>$offsetH+$layer['y']);

break;

case 'LB':

$offsetH=$dstH-$layer['height'];

$posOut=array('x'=>$layer['x'],'y'=>$offsetH-$layer['y']);

break;

case 'CT':

$offsetW=round(($dstW-$layer['width'])*1.0/2);

$posOut=array('x'=>$offsetW+$layer['x'],'y'=>$layer['y']);

break;

case 'CC':

$offsetW=round(($dstW-$layer['width'])*1.0/2);

$offsetH=round(($dstH-$layer['height'])*1.0/2);

$posOut=array('x'=>$offsetW+$layer['x'],'y'=>$offsetH+$layer['y']);

break;

case 'CB':

$offsetW=round(($dstW-$layer['width'])*1.0/2);

$offsetH=$dstH-$layer['height'];

$posOut=array('x'=>$offsetW+$layer['x'],'y'=>$offsetH-$layer['y']);

break;

case 'RT':

$offsetW=$dstW-$layer['width'];

$posOut=array('x'=>$offsetW-$layer['x'],'y'=>$layer['y']);

break;

case 'RC':

$offsetW=$dstW-$layer['width'];

$offsetH=round(($dstH-$layer['height'])*1.0/2);

$posOut=array('x'=>$offsetW-$layer['x'],'y'=>$offsetH+$layer['y']);

break;

case 'RB':

$offsetW=$dstW-$layer['width'];

$offsetH=$dstH-$layer['height'];

$posOut=array('x'=>$offsetW-$layer['x'],'y'=>$offsetH-$layer['y']);

break;

default:

$posOut=array('x'=>$layer['x'],'y'=>$layer['y']);

break;

}

return $posOut;

}

/*

取得剪裁部分的绝对位置

@param array $cropInfo 剪裁后图层的信息,包含width,height,x,y,pos等信息

@param array $layerInfo 目标图层的信息,包含width,height,x,y,pos等信息

*/

public static function getCropPos($cropInfo,$layerInfo){

switch ($cropInfo['pos']){

case 'LT':

$pos=array('x'=>$cropInfo['x'],'y'=>$cropInfo['y']);

break;

case 'LC':

$offsetHeight=round(($layerInfo['height']-$cropInfo['height'])*1.0/2);

$pos=array('x'=>$cropInfo['x'],'y'=>$cropInfo['y']+$offsetHeight);

break;

case 'LB':

$offsetHeight=$layerInfo['height']-$cropInfo['height'];

$pos=array('x'=>$cropInfo['x'],'y'=>$offsetHeight-$cropInfo['x']);

break;

case 'CT':

$offsetWidth=round(($layerInfo['width']-$cropInfo['width'])*1.0/2);

$pos=array('x'=>$offsetWidth+$cropInfo['x'],'y'=>$cropInfo['y']);

break;

case 'CC':

$offsetWidth=round(($layerInfo['width']-$cropInfo['width'])*1.0/2);

$offsetHeight=round(($layerInfo['height']-$cropInfo['height'])*1.0/2);

$pos=array('x'=>$offsetWidth+$cropInfo['x'],'y'=>$offsetHeight+$cropInfo['y']);

break;

case 'CB':

$offsetWidth=round(($layerInfo['width']-$cropInfo['width'])*1.0/2);

$offsetHeight=$layerInfo['height']-$cropInfo['height'];

$pos=array('x'=>$offsetWidth+$cropInfo['x'],'y'=>$offsetHeight-$cropInfo['y']);

break;

case 'RT':

$offsetWidth=$layerInfo['width']-$cropInfo['width'];

$pos=array('x'=>$offsetWidth-$cropInfo['x'],'y'=>$cropInfo['y']);

break;

case 'RC':

$offsetWidth=$layerInfo['width']-$cropInfo['width'];

$offsetHeight=round(($layerInfo['height']-$cropInfo['height'])*1.0/2);

$pos=array('x'=>$offsetWidth-$cropInfo['x'],'y'=>$offsetHeight+$cropInfo['y']);

break;

case 'RB':

$offsetWidth=$layerInfo['width']-$cropInfo['width'];

$offsetHeight=$layerInfo['height']-$cropInfo['height'];

$pos=array('x'=>$offsetWidth-$cropInfo['x'],'y'=>$offsetHeight-$cropInfo['y']);

break;

}

return $pos;

}

public static function sortLayers($a,$b){

if($a['level']>$b['level']){

return 1;

}else if($a['level']

return -1;

}else{

return 0;

}

}

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

photo.php,EasyPhoto.php 的相关文章

  • php字段验证规则,ThinkPHP 自动验证及验证规则详解

    ThinkPHP 自动验证及验证规则详解 ThinkPHP 自动验证 ThinkPHP 内置了数据对象的自动验证功能来完成模型的业务规则验证 自动验证是基于数据对象的 而大多情况下数据对象是基于 POST表单 不是绝对的 创建的 基本的自动
  • scrapy POST方式抓取走过的坑

    背景 今天老板让核查新上线的app中的中标数据展示情况 一条一条数据点开看实在是太慢了 于是想抓包获取app请求的api接口以及传入的参数 获取返回的数据内容 将数据存储到sqlite3中直接通过执行sql来统计数据质量 先打开fiddle
  • XSS quiz 1~5解题方案

    第1题 第一题很简单 没做过滤 直接可A过 第二题 查询框中写123查看源码 需要先闭合左边的input 所以 gt 即可 第三题 本题有过滤当输入 gt 时发现引号 尖括号都被过滤 lt gt 分别变成了转义符 尝试Unicode编码也未
  • antd Table中显示图片

  • qt 里面使用webengine

    qt使用webengine 条件 qt在windows上使用webengine必须用visual studio 使用mingw无效 webengine可以集成我们得html5页面 这样可以让界面开发人员更加省心 code 1 包含qwebe
  • YouTube上的版权保护

    早在2007年的时候 我曾写过一篇名为 YouTube The Big Copyright Lie YouTube 关于版权的弥天大谎 的文章 表达了我对YouTube又爱又恨的情感纠结 现在回想一下你在YouTube上看过的所有视频 它们
  • TabLayout+ViewPager+Fragment自定义tab添加小红点(kotlin事例)

    首先看哈效果 下面是两个布局 一个主布局 一个tab的布局 主布局很简单tablayout viewpager
  • Java制作JDK8文档搜索引擎项目并部署到阿里云服务器

    背景介绍 对于一个网站来说 搜索引擎需要提前预备好很多很多的静态资源 当用户输入查询的关键词的时候根据这些关键词来模糊查询匹配对应的资源 然后将这些资源展示给用户即可 搜索核心思路 互联网上主要是依赖于爬虫程序 它们可以极大效率的利用互联网
  • 视觉SLAM前端——直接法

    目录 直接法介绍 单层直接法 多层直接法 直接法介绍 这里所说的直接法不同于上一篇所说的LK光流法 LK光流是首先要选取特征点 如何利用特征点附近的光流进行路标的追踪与位姿的求解的 其本质还是先得到匹配好的点对 然后利用点对进行位姿估计 而
  • Matlab处理心电信号遇到的问题

    1 如何保存 Mat文件 运行上面的代码 在工作区会生成M mat文件 右键可以选择另存为 存到你想存的地址下面 2 得到了波形图和mat文件 然后对这个心电图进行滤波 该怎么处理 最笨的方法就是把 mat文件保存 另外再读取滤波 或者可以
  • Elasticsearch顶尖高手系列:核心知识篇(一)

    目录 1 第1 4节 第01节 课程介绍 第02节 什么是Elasticsearch 第03节 Elasticsearch的功能 适用场景以及特点介绍 第04节 Elasticsearch核心概念 NRT 索引 分片 副本等 2 第5 23
  • 极品开源工具,高糊照片有救了~

    今天给大家安利一款非常好用的AI图片修复工具 甭管你是模糊不清的老照片 还是高糊的表头包 头像 它统统都能帮你变成高清 效果那是嘎嘎攒劲 用过都说好 Upscayl 电脑 软件已在Github开源 版本齐全 Windows MacOS Li
  • 图的深度优先遍历

    深度优先搜素 Depth First Search DFS 是最常见的图的搜索之一 深度优先搜索沿着一条路径一直搜索下去 在无法搜索时 返回到刚刚访问的节点 深度优先的特征是 后被访问的节点 其领接点先被访问 根据深度优先遍历的特征 后来者
  • OSPF 详细总结。陆续更新

    OSPF 1 什么是OSPF OSPF 开放式最短路径优先 是一个基于链路状态进行路由计算的动态路由协议 主要用于大中型网络 2 OSPF的特点 不仅可以在一台路由器上运行多种OSPF路由进程 还可以把一个AS 自治系统 划分成多个不通的A
  • Java设计一个学生类Student,包含的属性有name和年龄age

    由学生类派生出本科生类Undergraduate和研究生类Postgraduate 本科生类包含的属性由专业specialty 研究生包含的属性有研究方向studydirection 重写Student类中的displayInformati
  • 安装Google Blockly Developer Tools离线版

    1 Blockly Developer Tools Demo在线版 https blockly demo appspot com static demos toolbox index html 注意 国内可能被墙导致该网址访问不了 可按如下
  • 物联网LoRa系列-18:LoRa终端Sx1262芯片内部高频电信号到中频电信号的变换(混频和变频)

    我们已经拆解了天线是如何发送和接收空中的高频无线电磁波信号 拆解了无线终端如何对射频前端的高频电信号进行进一步处理的 还拆解了无线终端的发送和接收如何分时复用天线的半双工模式 我们还拆解无线终端是如何对高频射频电信号进行进一步的处理 包括发
  • linux kvm 的虚拟机处于暂停状态怎么开机 和 KVM-Virsh指令

    root ok home virsh list Id Name State 1 13svn running 2 14git running 3 12c running 4 15samba running 5 win7
  • 地信

    准备 用的是qgis desktop 3 12 0 官网上下载即可 打开后页面 语言要修改成中文 setting option第一栏 算土地利用类型 双击新建项目 在浏览界面寻找双击打开自己要处理的数据 显示在图层中 图层可以上下拖动调整显

随机推荐

  • IT校招指南——超实用

    http blog csdn net liuqiyao 01 article details 26567237
  • JAVA方法(函数)的概念

    JAVA中函数的概念 什么是函数 答 函数英文称function 单一或相关联功能用来实现指定 要求功能的代码块 就是函数 函数在项目组可以直接进行调用且实现独立的功能 应对不同的实现需求的各种实现方法 就被称为函数 但主函数只有一个 主函
  • C语言Link_List简单实现

    C语言Link List简单实现 不做线程控制 Link List h 作者 代浩然 时间 2017 8 2 该文件定义为非线性链表相关的实现 线性链表的特性 1 在内存中的存放地址是非连续的 随机分配 优点 1 由于地址的非连续性 所以我
  • servlet注解 @WebListener

    Servlet3 0中的监听器跟之前2 5的差别不大 唯一的区别就是增加了对注解的支持 在3 0以前我们的监听器配置都是需要配置在web xml文件中的 在3 0中我们有了更多的选择 之前在web xml文件中配置的方式还是可以的 同时我们
  • C++程序设计初步和函数

    什么是基于过程的编程 定义 基于过程的程序设计反映的是事务在计算机中的实现方式 需要把实际中的步骤依次用程序编写出来 并给问题设计合适的数据结构 基于过程的思想由两部分组成 对数据的描述 即数据结构 数据相当于问题对象在计算机中的表述 对操
  • 5.Mybatis-plus_乐观锁和悲观锁

    乐观锁 故名思意十分乐观 它总是认为不会出现问题 无论干什么不去上锁 如果出现了问题 再次更新值测试 悲观锁 故名思意十分悲观 它总是认为总是出现问题 无论干什么都会上锁 再去操作 乐观锁实现方式 取出记录时 获取当前 version 更新
  • Javascript基本语法,a-href、img-src、button按钮使用时的跳转问题

    1 在中进行显示 2 对于返回值的问题 需要使用到alart 函数 其也存在return
  • HBase技术介绍

    HBase简介 HBase Hadoop Database 是一个高可靠性 高性能 面向列 可伸缩的分布式存储系统 利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群 HBase是Google Bigtable的开源实
  • 剑指Offer面试题5:替换空格程序调试与错误解决方法

    1 问题描述 面试题5 替换空格 题目 请实现一个函数 把字符串中的每个空格替换成 20 例如输入 We are happy 则输出 We 20are 20happy 2 程序代码 Copyright c 2016 Harry HeAll
  • 正确使用箭头函数——什么时候不该用ES6箭头函数

    正确使用箭头函数 什么时候不该用ES6箭头函数 原文地址 https segmentfault com a 1190000007074846 与君共勉 再牛逼的梦想 也抵不住傻逼般的坚持
  • Digital Camera Sensor 曝光三要素

    曝光三要素 曝光参数包括三要素 也就是相机曝光三角 相机孔径 ISO speed 曝光时间 相机孔径 光圈 控制通光面积 影响景深 光圈的面积越大 那么f指数越小 光圈的面积和F指数呈反比 F指数是焦距和光圈的反比 their light
  • 【JUC】Java并发编程学习笔记

    一 概述 1 为什么jdk中有那么多关于并发的类 并发可以理解为多线程同时工作 一般情况下是要比单线程处理速度更快 但是并发也不是在任何情况下都更优 使用多线程并发技术编写的代码在运行时可能会 发生线程上下文切换 上下文切换指的是内核在CP
  • 【华为OD技术面试真题精选 - 技术面】- Java八股文全题库(7)

    华为OD面试真题精选 强烈推荐 华为OD技术面试真题精选 大家好 今天我给大家推荐一份备受赞誉的华为OD技术面试精选题目 所有题目均为华为od实际面试过程中出现的问题 这些面试题主要涉及到编程八股文 职业态度以及独特的个性特点 让我们一起深
  • 云上社群系统部分接口设计详解与测试

    目录 一 项目简介 1 使用统一返回格式 全局错误信息定义处理前后端交互时的返回结果 2 使用 ControllerAdvice ExceptionHandler实现全局异常处理 3 使用拦截器实现用户登录校验 4 使用MybatisGen
  • Hadoop中Mapreduce的Job任务提交流程源码解析

    一 源码解析步骤 1 设置断点 在Driver的job任务提交打上断点进行Debug调试进入其中 F7 进入 F8 下一步 Alt Shift F7 强制进入 Shift F8 退出 进入waitForCompletion 2 submit
  • FastStone Capture 注册码

    name 用户名 92626key 注册码 HZKZBZLZ BOYHXDGD ONWD
  • Windows 10 Python 深度学习环境安装

    Windows 10 Python 深度学习环境安装 详细步骤和过程如下所示 1 安装Anaconda https repo anaconda com archive https repo anaconda com archive Anac
  • 晶体管放大、饱和、截止状态判断

    NPN晶体管 晶体管导通电压为Ube 直接测量 测得晶体管EBC极电压分别为Ue Ub Uc 若基极与发射极电势差小于导通电压 Ub Ue
  • 华为认证

    由于笔试考试系统升级 将会影响中国大陆区域2023年9月25日及之后的笔试考试预约 具体影响如下 1 2023年9月25日 27日预约 改期 取消笔试考试的考生 将会同时收到邮件和短信通知 9月28日07 00及之后预约 改期 取消笔试考试
  • photo.php,EasyPhoto.php

    class EasyPhoto 所有图层 private layers array 当前活动图层 private ActiveLayer 对象实例 单实例模式 private static instance private imageLay