gd - php中如何获得双色图片的mask
在php中如何实现上图的效果?要求:“上”和“爱情”都是通过程序自动输出的,程序能共自动判断画布上得空白部分并输出文字。
在python中,有pygame库直接获得一个画布的mask,然后提供collide函数来判断两个mask是否有交集。php是否有类似功能?
换个问题:
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 src="/static/imghw/default1.png" data-src="http://segmentfault.com/img/cJHB5O" class="lazy" data- 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>

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



In diesem Kapitel werden wir die Umgebungsvariablen, die allgemeine Konfiguration, die Datenbankkonfiguration und die E-Mail-Konfiguration in CakePHP verstehen.

PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

Um in cakephp4 mit Datum und Uhrzeit zu arbeiten, verwenden wir die verfügbare FrozenTime-Klasse.

Das Arbeiten mit der Datenbank in CakePHP ist sehr einfach. In diesem Kapitel werden wir die CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Löschen) verstehen.

Um am Datei-Upload zu arbeiten, verwenden wir den Formular-Helfer. Hier ist ein Beispiel für den Datei-Upload.

In diesem Kapitel lernen wir die folgenden Themen im Zusammenhang mit dem Routing kennen.

CakePHP ist ein Open-Source-Framework für PHP. Es soll die Entwicklung, Bereitstellung und Wartung von Anwendungen erheblich vereinfachen. CakePHP basiert auf einer MVC-ähnlichen Architektur, die sowohl leistungsstark als auch leicht zu verstehen ist. Modelle, Ansichten und Controller gu

Der Validator kann durch Hinzufügen der folgenden zwei Zeilen im Controller erstellt werden.
