ホームページ  >  記事  >  バックエンド開発  >  gd - php中如何获得双色图片的mask

gd - php中如何获得双色图片的mask

WBOY
WBOYオリジナル
2016-06-06 20:52:301033ブラウズ

gd - php中如何获得双色图片的mask

在php中如何实现上图的效果?要求:“上”和“爱情”都是通过程序自动输出的,程序能共自动判断画布上得空白部分并输出文字。

在python中,有pygame库直接获得一个画布的mask,然后提供collide函数来判断两个mask是否有交集。php是否有类似功能?

换个问题:
php中如何获得双色图片的mask

回复内容:

gd - php中如何获得双色图片的mask

在php中如何实现上图的效果?要求:“上”和“爱情”都是通过程序自动输出的,程序能共自动判断画布上得空白部分并输出文字。

在python中,有pygame库直接获得一个画布的mask,然后提供collide函数来判断两个mask是否有交集。php是否有类似功能?

换个问题:
php中如何获得双色图片的mask

更新下算法解释,貌似做成php版的还算简单
http://ued.ctrip.com/blog/?p=2471

携程的算法源码如下:

package com.ctrip;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.imageio.ImageIO;

public class WordsThumb
{
  public static final int MIN_WIDTH = 320;
  public static final int MIN_HEIGHT = 240;
  public static final int MAX_WIDTH = 2560;
  public static final int MAX_HEIGHT = 1920;
  public static final int BLOCK = 4;
  public static final String DEF_FONT = "微软雅黑";
  public static final int MIN_FONT_SIZE = 12;
  private static final int[] COLORS = { 11682842, 14439168, 
    13081114, 10300417, 14450176, 13052357, 11665801, 1739698, 
    101319, 84146, 15580865, 1722823, 6664705, 11257601, 
    7582257, 11665680, 14425600, 10768192, 14360836, 15515347, 
    111266, 49372, 15436032, 15436032 };

  public BufferedImage createWordsThumb(Map<string integer> words, int width, int height, String fontName, Integer maxFontSize, Integer minFontSize)
  {
    if ((words == null) || (words.size()  2560) || (height  1920))
      return null;
    fontName = validateFontName(fontName, "微软雅黑");
    List sortedWords = sortWordsMap(words);

    BufferedImage bi = createBufferedImage(width, height);
    if (bi == null) {
      return null;
    }
    if (maxFontSize == null) {
      maxFontSize = Integer.valueOf(Math.min(width, height) / 5);
    }
    if (minFontSize == null) {
      minFontSize = Integer.valueOf(Math.min(width, height) / 40);
    }
    if (minFontSize.intValue() > sortWordsMap(Map<string integer> words) {
    if (words == null)
      return null;
    ArrayList wordsList = new ArrayList(
      words.entrySet());
    Collections.sort(wordsList, 
      new Comparator()
    {
      public int compare(Map.Entry<string integer> o1, Map.Entry<string integer> o2)
      {
        return o2 == null ? -1 : o1 == null ? 1 : 
          ((Integer)o2
          .getValue()).intValue() - ((Integer)o1.getValue()).intValue();
      }
    });
    return wordsList;
  }

  private BufferedImage createBufferedImage(int width, int height) {
    BufferedImage bi = new BufferedImage(width, height, 
      2);
    Graphics2D g2 = bi.createGraphics();
    bi = g2.getDeviceConfiguration().createCompatibleImage(width, height, 
      3);
    g2.dispose();
    return bi;
  }

  private int paintWords(BufferedImage bi, List<map.entry integer>> words, String fontName, int maxFontSize, int minFontSize)
  {
    BitMap bitMap = initBitMap(bi);
    Graphics2D g2 = bi.createGraphics();
    int wordCount = 0;
    int fontSizeAdjust = 0;
    int maxFrequency = ((Integer)((Map.Entry)words.get(0)).getValue()).intValue();
    int minFrequency = ((Integer)((Map.Entry)words.get(words.size() - 1)).getValue()).intValue();
    for (Map.Entry entry : words)
    {
      while (true)
      {
        Font font = initFont(g2, fontName, Integer.valueOf(maxFontSize), Integer.valueOf(minFontSize), 
          (Integer)entry.getValue(), Integer.valueOf(maxFrequency), Integer.valueOf(minFrequency), 
          Integer.valueOf(fontSizeAdjust));
        if (font.getSize()  minFrequency.intValue()) {
      fs = (int)((frequency.intValue() - minFrequency.intValue()) * (
        maxFontSize.intValue() - minFontSize.intValue()) / (
        maxFrequency.intValue() - minFrequency.intValue()) + minFontSize.intValue());
    }
    if (fontSizeAdjust != null) {
      fs += fontSizeAdjust.intValue();
    }
    Font font = new Font(fontName, 1, fs);
    g2.setFont(font);
    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
      RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    return font;
  }

  private Rectangle2D getStringBounds(Graphics2D g2, Font font, String key)
  {
    FontRenderContext frc = g2.getFontRenderContext();

    Rectangle2D rc = font.getStringBounds(key, frc);

    return rc;
  }

  private Rectangle2D findSpace(BitMap bitMap, Rectangle2D rect) {
    int w = pixel2bitMap((int)rect.getWidth());
    int h = pixel2bitMap((int)rect.getHeight());
    int boundW = bitMap.getWidth() - w;
    int boundH = bitMap.getHeight() - h;
    int start_x = boundW / 2;
    int start_y = boundH / 2;

    int maxBound = Math.max(boundW, boundH);
    double wRatio = boundW / maxBound;
    double hRatio = boundH / maxBound;

    double max_r = Math.sin(0.7853981633974483D) * maxBound;
    double r = 1.0D; double a = 0.0D; double a_tmp = 0.0D; double s = 1.0D; double step = 1.0D;
    int x = start_x; int y = start_y;
    while (r  0.7853981633974483D ? 0.7853981633974483D : s / r;
      a += a_tmp;
      r += step * (a_tmp / 6.283185307179586D);
      x = (int)(Math.sin(a) * r * wRatio + start_x);
      y = (int)(Math.cos(a) * r * hRatio + start_y);
    }
    return null;
  }

  private Rectangle2D findSpace2(BitMap bitMap, Rectangle2D rect) {
    int w = pixel2bitMap((int)rect.getWidth());
    int h = pixel2bitMap((int)rect.getHeight());
    int[] bounds = { bitMap.getWidth() - w, 
      bitMap.getHeight() - h };

    int[] step_len = new int[2];
    int marchDir = 0;
    int x;
    int y;
    if (bounds[0] > bounds[1]) {
      int y = bounds[1] / 2;
      int x = y;
      bounds[0] -= bounds[1];
      step_len[1] = 1;
    } else {
      marchDir = 3;
      x = bounds[0] / 2;
      y = x;
      step_len[0] = 1;
      bounds[1] -= bounds[0];
      if (step_len[1] == 0) {
        step_len[1] = 1;
      }
    }

    int[] step = new int[4];
    while (!isClean(bitMap, x, y, w, h)) {
      step[marchDir] += 1;
      if (step[marchDir] > step_len[(marchDir % 2)]) {
        step[marchDir] = 0;
        step_len[(marchDir % 2)] += 1;
        marchDir++; marchDir %= 4;
        if (step_len[(marchDir % 2)] > bounds[(marchDir % 2)]) {
          return null;
        }
      }
      switch (marchDir) {
      case 0:
        x++;
        break;
      case 1:
        y--;
        break;
      case 2:
        x--;
        break;
      case 3:
        y++;
      }

    }

    int targetX = bit2pixel(x);
    int targetY = bit2pixel(y);
    return new Rectangle(targetX, targetY, (int)rect.getWidth(), 
      (int)rect.getHeight());
  }

  private int pixel2bitMap(int v) {
    return (int)Math.ceil(v / 4.0D);
  }

  private boolean isClean(BitMap bitMap, int x, int y, int w, int h) {
    if ((x = bitMap.getWidth()) || (y = bitMap.getHeight()))
      return false;
    for (int i = x; i  bi.getWidth())
      r = bi.getWidth();
    if (b > bi.getHeight())
      b = bi.getHeight();
    if ((r = bi.getWidth()) || (y2 >= bi.getHeight()))
            continue;
          if (bi.getRGB(x + i % 4, y + i / 4) != 0) {
            bitMap.setUsed(pixel2bitMap(x), pixel2bitMap(y), true);
            break;
          }
        }
  }

  public BufferedImage mixImages(BufferedImage[] images, Float[] alphas, int width, int height)
  {
    return mixImages(images, alphas, createBufferedImage(width, height));
  }

  public BufferedImage mixImages(BufferedImage[] images, Float[] alphas, BufferedImage targetImage)
  {
    if ((images == null) || (images.length ...");
      System.out.println("\t-o:\tOutput image file name");
      System.out.println("\t-b:\tBackground image file name");
      System.out.println("\t-m:\tWater mark image file name");
      System.out.println("\t-w:\tWidth of target image");
      System.out.println("\t-h:\tHeight of target image");
      System.out.println("\t-f:\tFont name");
      System.exit(1);
    }

    if (words.size()  words) throws IOException
  {
    BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("请输入词汇和词频,格式为每行一个词、一个空格、一个词频数字,以空行结束输入。");
    String line = null;
    while ((line = rd.readLine()) != null) {
      line = line.trim();
      if ("".equals(line)) {
        System.out.println("好,马上处理!");
        break;
      }
      String[] parts = line.split("\\s+");
      if (parts.length != 2) continue;
      try {
        words.put(parts[0], Integer.valueOf(Integer.parseInt(parts[1])));
      } catch (NumberFormatException e) {
        System.out.println("无效的输入。");
      }
    }
  }
}


package com.ctrip;

import java.io.IOException;
import java.io.PrintStream;

public class BitMap
{
  private byte[][] bitMap;
  private int width;
  private int height;
  private int byteWidth;

  public BitMap(int width, int height)
  {
    if ((width = 0 ? y : 0; for (int y2 = y1 - y; (y1 = 0 ? x : 0; for (int x2 = x1 - x; (x1 = 0 ? y : 0; for (int y2 = y1 - y; (y1 = 0 ? x : 0; for (int x2 = x1 - x; (x1 = this.byteWidth) || (y = this.height))
      throw new IllegalArgumentException();
    int mask = 1 = this.byteWidth) || (y = this.height))
      throw new IllegalArgumentException();
    int mask = 1 <p>反汇编工具jd-gui</p>
<p>写了一个flex版本的,执行时间大约1~2s,效果如下:<br>
<img  data-src="http://segmentfault.com/img/cJHB5O" alt="gd - php中如何获得双色图片的mask" ></p>
<p>源码layout.mxml:</p>
<pre class="brush:php;toolbar:false"><?xml version="1.0" encoding="utf-8"?>
<application xmlns:mx="http://www.adobe.com/2006/mxml" creationcomplete="onLoad();">
<style> 
 

@font-face{
	src:url("fanghei.ttf");
	font-family:myFont;
}

</style> 
<script>
mxmlc layout.mxml
///

import mx.controls.*;
import mx.core.*;
import mx.effects.*;
import flash.geom.Rectangle


private function clear():void
{
	my_text_input_1.text="clear it!";
}



private function add_text(text_array:Array, text:String):void
{
	text_array.push(text);
}

private function get_bmp_text(text:String):Bitmap
{
	var metrics:TextLineMetrics;
	var tempTextField:TextField = new TextField();

	var tempTextFormat:TextFormat = new TextFormat();
	tempTextFormat.font="myFont";
	tempTextFormat.size = Math.floor(Math.random() * 40 + 20);
	tempTextFormat.color = 0xff00FF;

	tempTextField.width = 200;
	tempTextField.height = 100;
	tempTextField.embedFonts = true;
	tempTextField.appendText(text);
	tempTextField.setTextFormat(tempTextFormat);

	metrics = tempTextField.getLineMetrics(0);
	var myBitmapData:BitmapData = new BitmapData(metrics.width, metrics.height, true ,0x0000FF);
	myBitmapData.draw(tempTextField);
	var myBmp:Bitmap = new Bitmap(myBitmapData);

	//本版本不支持rotation
	//如果要支持rotation,请参考http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/
	//myBmp.rotation = (Math.random() > 0.5)?0:90;

	return myBmp;
}

private function add_to_canvas(result:Array, bmpText:Bitmap):Boolean
{
	var last_angle:Number = 0;
	var last_radius:Number = 1;
	var x:int = 0;
	var y:int = 0;
	var center_x:int = 256;
	var center_y:int = 256;
	var width:int = 512;
	var height:int = 512;
	var conflict:Boolean = false;

	while(true)
	{
		last_angle = last_angle + 0.1;
		last_radius = last_radius + 0.1;
		x = Math.floor(last_radius * Math.cos(last_angle) + center_x);
		y = Math.floor(last_radius * Math.sin(last_angle) + center_y);
			
		bmpText.x = x;
		bmpText.y = y;

		conflict = false;
		if (result.length > 0)
		{
			var i:int;
			for(i = 0; i ";
			if (last_radius > width || last_radius > height)
			{
				conflict = true;
				break;
			}
		}
	}
	return !conflict;
}


private function draw(result:Array):void
{
	var s:Sprite = new Sprite;

	var i:int;
	for(i = 0; i </script>

	<label text="Hello World"></label>
	<label id="metrics_txt_1" text="Hello World" fontfamily="myFont"></label>
	<label id="metrics_txt_2" text="Hello World"></label>
	<textinput id="my_text_input_1" width="100" text=""></textinput>
	<button id="my_clear_button_1" label="clear" click="clear();"></button>

	<canvas backgroundcolor="0xFFFFFF" width="512" height="512" horizontalcenter="0" verticalcenter="0" id="canvas"></canvas>  
</application>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。